Ember.js - Get Result - ember.js

I am a beginner in Ember.js and I would like to get a response result and show in my view (HTML).
My Result:
{"teste": { "code": "1", "message": "hello" } }
My controller in Ember.js:
actions: {
discountCoupon: function() {
var lista = _this.store.find('teste', { "param": "123" });
console.info("return=" + lista.get('code'));
// result return===undefined
console.info("return===" + lista.get('message'));
// result return===undefined
},
...
}
My model:
import DS from 'ember-data';
export default DS.Model.extend({
code: DS.attr('string'),
message: DS.attr('string'),
});
I can't get the return of my backend.
Thanks in advance.

first you need to go and find what ever you are looking for, then you get your results. Remember When javascript promise you something will always give you a result back back....
actions: {
discountCoupon: function(){
var listas = _this.store.find('testes', {
param: "123"
}).then(function(lista){
console.log("return=" + lista.get('code'));
console.log("return===" + lista.get('message'));
});
},

One more thing, because you're using Ember Data and try to search using store.find('model', { queryParams }) Ember expects the backend to return a result in plural:
{"testes": [{"code":"1","message":"hello"}}]

Related

Ember Data: saving polymorphic relationships

I'm having trouble saving "hasMany" polymorphic records in Ember Data (1.0.0-beta.15). It looks as if Ember Data isn't setting the "type" property of the polymorphic relationship. Relationships in serialized records look like:
"roles": ["1", "2"]
When I expect them to look more like:
"roles":[{
"id": "1",
"type": "professionalRole"
}, {
"id": "2",
"type": "personalRole"
}
];
I see the following error in the console:
TypeError: Cannot read property 'typeKey' of undefined
If the records come back from the server in the expected format, all is well. The error only occurs when Ember Data creates the relationship.
I experience this using the FixtureAdapter, LocalStorageAdapter, and the RESTAdapter. I've read every piece of documentation I can find on the subject, but I cannot see my mistake.
I've created a CodePen to demonstrate the problem, but I'll also paste that code below.
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter;
App.Person = DS.Model.extend({
name: DS.attr(),
roles: DS.hasMany('role')
});
App.Role = DS.Model.extend({
title: DS.attr(),
person: DS.belongsTo('person', {
polymorphic: true
})
});
App.ProfessionalRole = App.Role.extend({
rank: DS.attr()
});
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
var person = this.store.createRecord('person', {
name: 'James'
});
var role = this.store.createRecord('professionalRole', {
title: 'Code Reviewer',
rank: 'Expert'
});
var promises = Ember.RSVP.hash({
person: person.save(),
role: role.save()
});
promises.catch(function() {
controller.set('initialSaveResult', 'Failure');
});
promises.then(function(resolved) {
controller.set('initialSaveResult', 'Success!');
var resolvedPerson = resolved.person;
var resolvedRole = resolved.role;
// Either/both of these break it
//resolvedRole.set('person', resolvedPerson);
resolvedPerson.get('roles').addObject(resolvedRole);
var innerPromises = Ember.RSVP.hash({
person: resolvedPerson.save(),
role: resolvedRole.save()
});
innerPromises.catch(function() {
controller.set('secondSaveResult', 'Failure');
});
innerPromises.then(function() {
controller.set('secondSaveResult', 'Success!');
});
});
}
});
App.ApplicationController = Ember.Controller.extend({
initialSaveResult: "Loading...",
secondSaveResult: "Loading..."
});

Implementing model filter

I have set up the following scaffolding for my Ember application.
window.App = Ember.Application.create({});
App.Router.map(function () {
this.resource('coaches', function() {
this.resource('coach', {path: "/:person_id"});
});
});
App.ApplicationAdapter = DS.FixtureAdapter.extend({});
App.Person = DS.Model.extend({
fname: DS.attr('string')
,lname: DS.attr('string')
,sport: DS.attr('string')
,bio: DS.attr('string')
,coach: DS.attr('boolean')
,athlete: DS.attr('boolean')
});
App.Person.FIXTURES = [
{
id: 10
,fname: 'Jonny'
,lname: 'Batman'
,sport: 'Couch Luge'
,bio: 'Blah, blah, blah'
,coach: true
,athlete: true
}
,{
id: 11
,fname: 'Jimmy'
,lname: 'Falcon'
,sport: 'Cycling'
,bio: 'Yada, yada, yada'
,coach: false
,athlete: true
}
];
I am trying to set up a route to filter the person model and return only coaches. Just to make sure I can access the data, I have simply used a findAll on the person model.
App.CoachesRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('person');
}
});
Now though, I am trying to implement the filter method detailed on the bottom of the Ember.js Models - FAQ page.
App.CoachesRoute = Ember.Route.extend({
model: function() {
var store = this.store;
return store.filter('coaches', { coach: true }, function(coaches) {
return coaches.get('isCoach');
});
}
});
The coaches route is not working at all with the new route implemented and the old one commented out. I am using the Ember Chrome extension and when using the filter route the console responds with, Error while loading route: Error: No model was found for 'coaches'. Apparently the route is not working, specifically the model. No kidding, right? What am I missing in my filter model route?
Thank you in advance for your help.
The error message is spot on- there is no CoachModel. I think you need to do this:
App.CoachesRoute = Ember.Route.extend({
model: function() {
var store = this.store;
return store.filter('person', { coach: true }, function(coaches) {
return coaches.get('isCoach');
});
}
});

How to correctly access a parent controllers data (model) in nested resources?

I have a little EmberJS app to test things out hot to do nested resources. Sometimes accessing a parent routes/controllers data work, other times not.
Most likely this is due to a oversight on my part with how EmberJS does its magic.
Here is the app:
window.App = Ember.Application.create();
App.Router.map(function() {
this.resource('items', function() {
this.resource('item', {path: ':item_id'}, function() {
this.resource('subitems');
});
});
});
App.ApplicationController = Ember.Controller.extend({
model: {
items: [
{
id: 1,
name: 'One',
subitems: [
{
id: 1,
name: 'One One'
}, {
id: 2,
name: 'One Two'
}
]
}, {
id: 2,
name: 'Two',
subitems: [
{
id: 3,
name: 'Two One'
}, {
id: 4,
name: 'Two Two'
}
]
}
]
}
});
App.ItemsRoute = Ember.Route.extend({
model: function() {
return this.controllerFor('Application').get('model.items')
}
});
App.ItemRoute = Ember.Route.extend({
model: function(params) {
var items = this.controllerFor('Items').get('model')
var item = items.filterBy('id', parseInt(params.item_id))[0]
return item
}
});
App.SubitemsRoute = Ember.Route.extend({
model: function(params) {
var item = this.controllerFor('Item').get('model')
var subitems = item.get('subitems')
return subitems
}
});
http://jsfiddle.net/maxigs/cCawE/
Here are my questions:
Navigating to items/1/subitems throws an error:
Error while loading route: TypeError {} ember.js:382
Uncaught TypeError: Cannot call method 'get' of undefined test:67
Which i don't really get, since apparently the ItemController loads its data correctly (it shows up) and the same construct works for the ItemsRoute as well to get its data.
Since i don't have access to the parents routes params (item_id) i have no other way of re-fetching the data, even though directly accessing the data from ApplicationController works fine.
Why do i have define the root data in a controller not route?
Moving the model definition from ApplicationController to ApplicationRoute, does not work.
Conceptually, as far as i understand it, however this should even be the correct way to do it, since everywhere else i define the mode data for the controller int he route.
Or should the whole thing be better done via the controllers needs-api? As far as i understood the needs are more for only accessing extra data within the controller (or its view) but the routers job is to provide the model.
1. Navigating to items/1/subitems throws an error:
Your model is just a javascript object so there isn't a method get to fetch the data. You can access the subitems by just executing item.subitems.
Also the argument of controllerFor() should be lower case.
For instance:
this.controllerFor('application')
2. Why do i have define the root data in a controller not route?
You can set the model from the route in the setupController method.
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('model', { ... });
}
});
http://jsfiddle.net/Y9kZP/
After some more fiddling around here is a working version of the example in the question:
window.App = Ember.Application.create();
App.Router.map(function() {
this.resource('items', function() {
this.resource('item', {path: ':item_id'}, function() {
this.resource('subitems');
});
});
});
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return Ember.Object.create({
items: [
Ember.Object.create({
id: 1,
name: 'One',
subitems: [
{
id: 1,
name: 'One One'
}, {
id: 2,
name: 'One Two'
}
]
}), Ember.Object.create({
id: 2,
name: 'Two',
subitems: [
{
id: 3,
name: 'Two One'
}, {
id: 4,
name: 'Two Two'
}
]
})
]
})
}
});
App.ItemsRoute = Ember.Route.extend({
model: function() {
return this.modelFor('application').get('items')
}
});
App.ItemRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('items').findProperty('id', parseInt(params.item_id))
}
});
App.SubitemsRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('item').get('subitems')
}
});
http://jsfiddle.net/maxigs/cCawE/6/ and deep link into subitems (that did not work previously) http://fiddle.jshell.net/maxigs/cCawE/6/show/#/items/2/subitems
What changed:
root-model data moved into ApplicationRoute
root-model moved into an ember object, and sub-objects are also their own ember objects (so calling get('subitems') and other ember magic works)
changed all the controllerFor('xxx').get('model') into modelFor('xxx') (lower case!), which probably has no effect other than consistency
I'm still not sure if this is now "the ember way" of doing what i have here but its consistent and works completely as wanted.

Ajax without ember data - Uncaught TypeError: Object #<Object> has no method 'forEach'

I'm attempting to build a non blocking async call in an Ember.js app without using Ember Data.
I have the following Ember.js model:
App.Player = Ember.Object.extend({
id: '',
alias: '',
name: '',
twitterUserName: '',
isFeatured: ''
});
App.Player.reopenClass({
getPlayers: function () {
var players = Ember.ArrayProxy.create({ content: [] });
$.getJSON("/api/players").then(function (response) {
response.forEach(function (p) {
players.pushObject(App.Player.create(p));
});
});
return players;
}
});
And I am calling it as follows in my route:
App.IndexRoute = Ember.Route.extend({
model: function (params) {
return App.Player.getPlayers();
}
});
For some reason I am getting the following javascript error:
Uncaught TypeError: Object # has no method 'forEach'
I've tried a few variants I have seen around but nothing seems to work. Any help would be appreciated...
EDIT - Found the solution with some help from Darshan, here's the working code:
App.Player.reopenClass({
getPlayers: function () {
var players = [];
$.ajax({
url: "/api/players",
}).then(function (response) {
response.players.forEach(function (player) {
var model = App.Player.create(player);
players.addObject(model);
});
});
return players;
}
});
Your response.forEach suggests that you are expecting the json response body to be an array. It is probably wrapped in some root element like players or data like so.
{
"players": [...]
}
If that is the case you need to use forEach on that root element like response.players.forEach.
You also want to restructure that code to return a promise directly. The Ember router will then pause until your json is loaded and only proceed after it finishes. Something like this,
getPlayers: function () {
return $.getJSON("/api/players").then(function (response) {
var players = Ember.ArrayProxy.create({ content: [] });
response.players.forEach(function (p) {
players.pushObject(App.Player.create(p));
});
return players;
});
}
Returning players resolve the promise. And Ember understands that when a promise resolves that result is the model.

Embedded hasMany attribute access gives "TypeError: Cannot call method 'hasOwnProperty' of undefined"

Using:
Ember commit a5d45f66e1 from Jan 3, 2013)
Ember-Data commit 508479dee7 from Jan 4, 2013
Similar to this question ('Unable to get hasMany association'), I am unable to access embedded hasMany records directly but can see them through the model's content attribute.
For JSON:
{
"ref_book_search":{
"query":"har",
"results":[
{
"publisher":{
"name":"Pangolin",
"created":"2012-09-10T18:38:27.259515",
"id":"3d2028e4fb91181e1a6e012313914f821",
"is_active":true,
"main_url":null,
"resource_uri":"/api/v1/ref_publisher/3d2028e4fb91181e1a6e012313914f821"
},
"genre":"romcom",
"id":"cc671f00fc2711e1e41612313914f821",
"resource_uri":"/api/v1/ref_book/cc671f00fc2711e1e41612313914f821",
"title":"Harry Placeholder and the Goblet of PBR"
},
{
"publisher":{
"name":"Hoof & Mouth",
"created":"2012-10-10T14:31:27.259515",
"id":"3d200e9afb9811e1a27417383914f821",
"is_active":true,
"main_url":null,
"resource_uri":"/api/v1/ref_publisher/3d200e9afb9811e1a27417383914f821"
},
"genre":"horror",
"id":"cc621f08fc2711e1b81612313914e821",
"resource_uri":"/api/v1/ref_book/cc621f08fc2711e1b81612313914e821",
"title":"Harvey Weinstein Holiday Cookbook"
}
]
}
}
And app.js (note the map statements, which were the solution suggested in the prior question):
var App = Ember.Application.create();
DS.RESTAdapter.configure("plurals", {"ref_book_search" : "ref_book_search"});
App.store = DS.Store.create({
revision: 11,
adapter: DS.RESTAdapter.create({
bulkCommits: false,
namespace: "api/v1"
})
});
DS.RESTAdapter.map('App.RefBookSearch', {
primaryKey: 'query'
});
App.store.adapter.serializer.map('App.RefBookSearch', {
results: {embeddded: 'load'}
});
App.store.adapter.serializer.map('App.RefBook', {
publisher: {embeddded: 'load'}
});
App.RefPublisher = DS.Model.extend({
name : DS.attr('string'),
created : DS.attr('date'),
isActive : DS.attr('boolean'),
mainUrl : DS.attr('string')
});
App.RefBook = DS.Model.extend({
publisher: DS.belongsTo('App.RefPublisher'),
title : DS.attr('string'),
genre : DS.attr('string')
});
App.RefBookSearch = DS.Model.extend({
query: DS.attr('string'),
results: DS.hasMany('App.RefBook')
});
App.Router.map(function(match) {
match('/').to('query'),
match('/query/:ref_book_search_id').to('query')
});
App.QueryController = Ember.Controller.extend({
bookSearch: null,
results: []
});
App.QueryRoute = Ember.Route.extend({
setupControllers: function(controller, refBookSearch) {
controller.set('bookSearch', refBookSearch)
controller.set('results', refBookSearch.get('results').content)
}
})
App.initialize();
Everything looks fine at first, just like other poster:
search = App.RefBookSearch.find('ha')
search.get('query')
// => "ha"
results = search.get('results')
results.get('firstObject') instanceof App.RefBook
// => true
But then:
results.forEach(function(result) { console.log(result.get('title')) })
// => TypeError: Cannot call method 'hasOwnProperty' of undefined
Accessing via content shows the data is there:
results.content.forEach(function(result) { console.log(result.title) })
// => Harry Placeholder and the Goblet of PBR
// => Harvey Weinstein Holiday Cookbook
Now if I try accessing directly again, I get a slightly different error:
results.forEach(function(result) { console.log(result.get('title')) })
// => undefined x 2
This may or may not be related to this bug filed a few days ago.
I feel like I've tried everything here; I hope I'm just missing something simple. Any pointers very much appreciated. Thanks.
This is what ultimately worked for me. There seems to be some order-of-operations sensitivity i.e., doing the configure and map before creating the store. Also note that adapter.map is a convenience function that performs the mapping on the serializer.
App.Adapter = DS.RESTAdapter.extend()
App.Adapter.configure("plurals", {
"ref_book_search" : "ref_book_search",
"ref_book" : "ref_book",
"ref_publisher" : "ref_publisher"
});
App.Adapter.configure('App.RefBookSearch', {
primaryKey: 'query'
});
App.Adapter.map('App.RefBookSearch', {
results: {'embedded': 'load'}
});
App.Adapter.map('App.RefBook', {
publisher: {'embedded': 'load'}
});
App.store = DS.Store.create({
revision: 11,
adapter: App.Adapter.create({
bulkCommits: false,
namespace: "api/v1"
})
});