How to use belongsTo in ember-model? - ember.js

I have created FIXTURES using ember-model, but i am not able to use following node on template
"logged_in": {
"id" : "1",
"logged": true,
"username": "sac1245",
"account_id": "4214"
}
I have implemented belongsTo relation for this node but it throwing one error : Uncaught Error: Ember.Adapter must implement findQuery
Here i have listed my model code :
Astcart.Application = Ember.Model.extend({
name: Ember.attr(),
logo_url : Ember.attr(),
list: Ember.hasMany('Astcart.List', {key: 'list', embedded: true}),
logged_in: Ember.belongsTo('Astcart.Logged_in', {key: 'logged_in'})
});
Astcart.List = Ember.Model.extend({
name: Ember.attr()
});
Astcart.Logged_in = Ember.Model.extend({
id: Ember.attr(),
logged: Ember.attr(),
username: Ember.attr(),
account_id: Ember.attr()
});
Astcart.Application.adapter = Ember.FixtureAdapter.create();
Astcart.Application.FIXTURES = [
{
"id" : "1",
"logo_url": "img/logo.jpg",
"logged_in": {
"id" : "1",
"logged": true,
"username": "sac1245",
"account_id": "4214"
},
"name": "gau",
"list": [
{
"id" : "1",
"name": "amit"
},
{
"id" : "2",
"name": "amit1"
}
]
}
];
Template code :
{{#each item in model}}
{{item.name}}
{{item.logged_in.logged}}
{{/each}}
Router code :
Astcart.ApplicationRoute = Ember.Route.extend({
model: function() {
return Astcart.Application.find();
}
});
Can any one show me how to access data of above node in template?

Your current fixture have the logged_in data embedded:
Astcart.Application.FIXTURES=[
{
...
"logged_in": {
"id": "1",
"logged": true,
"username": "sac1245",
"account_id": "4214"
},
...
}
];
So the logged_in property mapping need the parameter embedded: true, to be able to find this data, as follow:
Astcart.Application = Ember.Model.extend({
...
logged_in: Ember.belongsTo('Astcart.Logged_in', {key: 'logged_in', embedded: true })
});
Without this it will try to query for the Astcart.Logged_in:
Astcart.Logged_in.find(1)
and because it doesn't have an adapter, will fail with the exception: Uncaught Error: Ember.Adapter must implement findQuery
You can see this working in that fiddle http://jsfiddle.net/marciojunior/8zjsh/

Related

How to display attributes of belongsTo object in Ember.js template

In my Ember app, a survey belongsTo a user; a user hasMany surveys. In my template, I would like to display a list of surveys, and the name of the user that created them. For now, I am pushing side-loaded data into the store via the application route, and it is showing up in the ember inspector->Data. The survey info is displaying correctly in the template, but the corresponding user's firstName will not appear. Help/guidance appreciated.
survey.js (model)
import DS from 'ember-data';
export default DS.Model.extend({
user: DS.belongsTo('user', {async: true}), //tried without async as well
title: DS.attr(),
post: DS.attr()
});
user.js (model)
import DS from 'ember-data';
export default DS.Model.extend({
surveys: DS.hasMany('survey', {async: true}),
firstName: DS.attr()
});
application.js (application route)
export default Ember.Route.extend({
model() {
this.store.push({
data: [{
id: 1,
type: 'survey',
attributes: {
title: 'My First Survey',
post: 'This is my Survey!'
},
relationships: {
user: 1
}
}, {
id: 2,
type: 'survey',
attributes: {
title: 'My Second Survey',
post: 'This is survey 2!'
},
relationships: {
user: 1
}
}, {
id: 1,
type: 'user',
attributes: {
firstName: 'Tyler'
},
relationships: {
surveys: [1, 2]
}
}]
});
}
});
surveys.js (route)
export default Ember.Route.extend({
model () {
return this.store.findAll('survey');
}
});
surveys.hbs (template)
<ul>
{{#each model as |survey|}}
<li>
<strong>{{survey.title}}</strong> //This works
<br>
{{survey.post}} //This works
<br>
Author: {{survey.user.firstName}} //This does not work
</li>
{{/each}}
</ul>
SOLUTION - updated application.js
export default Ember.Route.extend({
model() {
this.store.push({
"data": [ //Added double quotes throughout to conform to documentation
{
"id": "1",
"type": "survey",
"attributes": {
"title": "My First Survey",
"post": "This is my Survey!"
},
"relationships": {
"user": {
"data": {
"id": "1",
"type": "user"
}
}
}
}, {
"id": "2",
"type": "survey",
"attributes": {
"title": "My Second Survey",
"post": "This is survey 2!"
},
"relationships": {
"user": {
"data": {
"id": "1",
"type": "user"
}
}
}
}
],
"included": [
{
"id": "1",
"type": "user",
"attributes": {
"firstName": "Tyler"
} //no need to include user's relationships here
}
]
});
}
});
Payload relationship part is not correct. Should be:
relationships: {
user: {
data: {
id: 1,
type: 'user'
}
}
}
Also I think "user" payload should be in "included" section.
JSONAPISerializer api

async: true still requires associated Model in Ember

I've got two Models using ember-data:
App.Post = DS.Model.extend({
'comments': DS.hasMany('comment', {async: true})
});
App.Comment = DS.Model.extend({
postId: DS.belongsTo('post', {async: true})
});
When I try to get the Posts via a Route
model: function(params) {
return this.store.find('post', params.query);
}
Ember tries to find the Comments, which are not Part of the Posts Response from the API, although "async" is set to true.
Cannot read property 'comments' of undefined
Update
Some more detailed informations, complementing the information above:
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://api.example.com'
});
App.ApplicationController = Ember.Controller.extend({
actions: {
search: function() {
var term = this.get('query');
this.transitionToRoute('post', { query: term });
},
reset: function() {
clearTimeout(this.get("timeout"));
this.setProperties({
isProcessing: false,
isSlowConnection: false
});
}
}
});
App.Router.map(function() {
this.resource('post', { path:'/:query' }, function(){
this.route('create');
this.route('edit');
});
});
App.PostRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.query);
}
});
Data
"posts": [
{
"id": 1,
"title": "Lorem ipsum",
"comments": ["1", "2"],
},
{
"id": 2,
"title": "dolor sit amet",
"comments": ["1", "2"],
}
]
And
"comments": [
{
"id": "1",
"body": "comment content 1",
"postId": 1
},
{
"id": "2",
"body": "comment content 2",
"postId": 1
}
]
If you wanna get information that is already loaded on the store you need to use
this.store.all('post')
And then use filter to get the information you want as an example
this.store.all('post').filterBy('key', value)
have a look at the documentation for further information on filtering if you need
http://emberjs.com/guides/enumerables/
As stated in a comment from ShinySides answer, Ember expects an object, instead of an array, because of the routing: if you got the route /posts the responded JSON has to be an Array with all posts:
"posts": [
{
"id": 1,
"title": "Lorem ipsum",
"comments": ["1", "2"],
},
]
But for the route /posts/search-for-whatever-in-posts Ember expects an object, representing just one post:
"post": {
"id": 1,
"title": "Lorem ipsum",
"comments": ["1", "2"],
},
The solution for my question: QUERYING FOR RECORDS:
var posts = this.store.find('posts', { term: "search for whatever in posts" });
which adds a parameter "term" to the API request (e.g. api.example.com/posts?term=whatever). Ember will now return an array.

error when upgrading to ember-data beta2

I'm getting this error when trying to load a set of records through a restful api. It works with ember-model but when I switch to ember-data (beta 2) and ember.js (1.0), I get this error.
Assertion failed: No model was found for '0'
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:8080',
namespace: 'api'
});
App.Router.map(function() {
this.resource('about');
this.resource('pages', function() {
this.resource('page', { path: ':page_id' });
});
this.resource('login');
});
App.AuthenticatedRoute = Ember.Route.extend({
actions: {
error: function(reason, transition) {
if (reason.status == 403) {
alert('You must login');
this.transitionTo('login');
}
else {
//alert('non 403 error:'+reason.status);
this.transitionTo('login');
}
}
}
});
App.PagesRoute = Ember.Route.extend({
model: function() {
return this.store.find('page');
}
});
App.PageRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('page', params.page_id);
}
});
App.Page = DS.Model.extend({
user: DS.attr('string'),
slug: DS.attr('string'),
zcontent: DS.attr(),
title: DS.attr('string'),
create_time: DS.attr('date'),
update_time: DS.attr('date')
});
Here is what the backend returned:
{
"pages": [
{
"update_time": "2013-01-14 19:59:35.744855",
"title": "",
"id": 38,
"create_time": "2012-08-04 15:08:16",
"user": "robert-jones",
"slug": "orange"
},
{
"update_time": "2013-01-14 19:59:35.899830",
"title": "",
"id": 47,
"create_time": "2012-08-03 10:04:07",
"user": "robert-jones",
"slug": "REVIEWStheraputics"
},
{
"update_time": "2012-12-18 07:16:13.656509",
"title": "'Notes on Temperature Heat Map'",
"id": 17,
"create_time": "2012-12-18 07:14:48.118119",
"user": "robert-jones",
"slug": "50612c27b94ca650"
},
{
"update_time": "2012-12-12 19:48:08.079021",
"title": "'Notes on Dyanmic Heat Map'",
"id": 8,
"create_time": "2012-12-12 19:48:08.013336",
"user": "robert-jones",
"slug": "c5642b4c14d901cf"
}
]
}
I've run into this before when my server was just returning a raw array instead of an object with a root element. That is, instead of this:
{pages : [...]}
I was accidentally returning this:
[...]
Kind of hard to say without a JSBin to look at.

Trouble consuming json rest data in ember-data

I'm trying to parse a json dataset in my ember data models but this throws an error in het console:
Uncaught TypeError: Cannot call method '_create' of undefined
DS.Store.Ember.Object.extend.materializeRecord
DS.Store.Ember.Object.extend.findByClientId
What am I doing wrong here?
This is the data I receive from the server:
{
"newsitems": [
{
"date": "2013-02-10T15:00:00+01:00",
"id": "1",
"images": [
{
"id": "1",
"value": "image.JPG"
},
{
"id": "3",
"value": "anotherimage.jpg"
}
],
"slug": "some-slug",
"summary": "some summary",
"text": "some text",
"thumb": {
"id": "2",
"value": "someimage.JPG"
},
"title": "Some title",
"type": "1",
"videos": [
{
"id": "AEOpX8tmiUI",
"value": "AEOpX8tmiUI"
},
{
"id": "kxopViU98Xo",
"value": "kxopViU98Xo"
}
]
}
]
}
These are my models:
App.NewsitemThumb = DS.Model.extend({
value: DS.attr('string'),
newsitem: DS.belongsTo('App.Newsitem')
});
App.NewsitemImage = DS.Model.extend({
value: DS.attr('string'),
newsitem: DS.belongsTo('App.Newsitem')
});
App.NewsitemVideo = DS.Model.extend({
value: DS.attr('string'),
newsitem: DS.belongsTo('App.Newsitem')
});
App.Newsitem = DS.Model.extend({
slug: DS.attr('string'),
type: DS.attr('string'),
title: DS.attr('string'),
summary: DS.attr('string'),
text: DS.attr('string'),
date: DS.attr('date'),
thumb: DS.belongsTo('App.NewsitemThumb'),
images: DS.hasMany('App.NewsitemImage'),
videos: DS.hasMany('App.NewsitemVideo')
});
For the record, any suggestions for optimizing these models are welcome. It feels so weird to make 3 models for video, images and a thumb.
According to this issue, this error pops up when you don't specify an explicit mapping for a hasMany relationship in your adapter.
Try defining your store as
App.Store = DS.Store.extend({
revision: 11,
adapter: DS.RESTAdapter.extend({
serializer: DS.RESTSerializer.extend({
init: function() {
this._super();
this.map("App.Newsitem", {
images: { embedded: "load" },
videos: { embedded: "load" }
});
}
})
})
});

List paging from json

I am finaly able to retrieve my datas from the json file BUT the paging system still sucks. The pageSize property seems not to respond therefore when i press on the load more plugin text that appears at the bottom of my list, it appends all my json elements to my list everytime. I am confident about the fact that i am almost there but i can't see how to make it happen.
Here is the code:
Ext.setup({
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: false,
onReady : function() {
var dataLink;
if (Ext.is.Desktop) {
dataLink = "http://127.0.0.1/Appsfan-v2";
} else {
dataLink = "http://appsfan.kreactive.eu";
}
Ext.regModel('Profile', {
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'},
{name: 'age', type: 'number'}
]
});
var store = new Ext.data.JsonStore({
model: 'Profile',
autoLoad: false,
remoteFilter: true,
sortOnFilter: true,
//sorters: [{property : 'lastname', direction: 'ASC'}],
pageSize: 1,
clearOnPageLoad: false,
proxy: {
type: 'ajax',
url: dataLink+'/data.json',
reader: {
root: 'profile',
type: 'tree'
}
}
});
console.log(store)
//console.log(store.loadPage(0))
var groupingBase = new Ext.List({
fullscreen: true,
itemTpl: '<div class="contact2"><strong>{firstname}</strong> {lastname} -> {age}</div>',
indexBar: false,
store: store,
plugins: [{
ptype: 'listpaging',
autoPaging: false
}]
});
var panel = new Ext.Panel({
layout: 'card',
fullscreen: true,
items: [groupingBase],
dockedItems: [{
xtype: 'toolbar',
title: 'paging example',
}]
})
//console.log(datas)
}
});
The json
{
"profile": [{
"firstname": "firstname1",
"lastname": "lastname1",
"age": "1"
},{
"firstname": "firstname2",
"lastname": "lastname2",
"age": "2"
},{
"firstname": "firstname3",
"lastname": "lastname3",
"age": "3"
}]
}
Thank you
You can set the clearOnPageLoad config option in your store. This will remove previous records when the next page of the paginated data is loaded.
Here is an example:
Ext.regStore('BarginsStore', {
model: 'BarginModel',
autoLoad: false,
pageSize: 6,
clearOnPageLoad: false,
});