Accessing Nested JSON in Ember Model - ember.js

I'm trying to access a particular ID which is nested inside my model to make a belongsTo association. I have no trouble getting what I need in my template, but need image_id within my model. Below is my JSON and current model.
{
content: {
title: 'Title',
header: 'Header',
image_id: 1
}
slug: 'slug',
title: 'Welcome'
}
Here is my current model...
import DS from 'ember-data';
const { attr } = DS;
export default DS.Model.extend({
content: attr(),
title: attr('string'),
});
Hope this makes sense!! Thanks!

I have similar use-cases (mostly a very variable settings paramter that is stored as json in db) and solved it via a custom transform:
// myapp/transforms/json.js
import DS from 'ember-data';
// Converts stringified json coming from database (usually in table-field 'settings') to a POJO
export default DS.Transform.extend({
deserialize: function(serialized) {
return JSON.parse(serialized);
},
serialize: function(deserialized) {
return JSON.stringify(deserialized);
}
});
//myapp/models/myModel.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
content: DS.attr('json')
});
Then in your template you should be able to do
{{model.content.image_id}}
Or in controller
let image_id = this.get('model.content.image_id');
or in model
this.get('content.image_id');

Related

findAll throwing error

I am using a simple findAll query in my ember application ( ember-version: 2.12.0, ember-data-version: 2.12.1 ) and I get the following error:
Assertion Failed: You can no longer pass a modelClass as the first argument to store.buildInternalModel. Pass modelName instead.
I am using the RESTAdapter and RESTSerializer.
Here is my team model:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
projects: DS.hasMany('project'),
users: DS.hasMany('user'),
members: Ember.computed('users', function() {
return this.get('users.content.length');
}),
leader: DS.belongsTo('user', {
inverse: 'team'
})
});
and my team serializer:
import ApplicationSerializer from './application';
import DS from 'ember-data';
export default ApplicationSerializer.extend(DS.EmbeddedRecordsMixin,{
attrs: {
users: { async: true },
projects: { async: true }
}
});
Despite the error, the team objects I requested are in the store. I had no luck in solving this so far.
Actually the problem was in the serializer and the payload from the server. I should have attrs: {users: {embedded: 'always'}} as users where in the payload from the server.

You need to pass a model name to the store's modelFor method

I have problem with making hasMany <=> belongTo relationship to work.
I have articles/show view, when I try to list article's comments but I keep recieving the error pointed in the title.
It's something with belongsTo: DS.belongsTo('article') but I couldn't figure out what it is.
Here are my files.
routes/articles/show.js
import Ember from 'ember';
import RSVP from 'rsvp';
export default Ember.Route.extend({
model(params) {
return RSVP.hash({
article: this.store.find("article", params.id),
comments: this.store.query('comment', { articleId: params.id })
});
}
});
controllers/articles/show.js
import Ember from 'ember';
const { computed: { alias, readOnly } } = Ember;
export default Ember.Controller.extend({
article: alias('model.article'),
comments: alias('model.comments'),
length: readOnly('comments.length')
});
templates/articles/show.hbs
<h3>Comments ({{comments.length}})</h3>
{{#each comments as |comment|}}
<p>Author: {{comment.user.name}}</p>
<p>Somebody said: {{comment.body}}</p>
{{/each}}
adapters/comment.js
import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({});
serializers/comment.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
attrs: {
user: { embedded: 'always' },
article: { embedded: 'always' }
}
});
serializers/article.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
comments: { embedded: 'always' }
}
});
models/article.js
import DS from 'ember-data';
import Ember from 'ember';
const { attr, hasMany } = DS;
const { computed: { gt } } = Ember;
export default DS.Model.extend({
title: attr('string'),
content: attr('string'),
authorName: attr('string'),
authorAvatar: attr('string'),
authorUrl: attr('string'),
comments: hasMany('comment', {async: true}),
hasAvatar: gt('authorAvatar.length', 0)
});
Edit:
I added here the code for comment model as asked in the comments.
models/comment.js
import DS from 'ember-data';
const { belongsTo, attr } = DS;
export default DS.Model.extend({
article: belongsTo(),
user: belongsTo(),
body: attr('string')
});
And here is stacktrace from inspector:
ember.debug.js:16905 Assertion Failed: You need to pass a model name to the store's modelFor method
Error
at assert (http://ffl.com:8000/assets/vendor.js:16268:13)
at Object.assert (http://ffl.com:8000/assets/vendor.js:27196:34)
at assert (http://ffl.com:8000/assets/vendor.js:135212:37)
at Class.modelFor (http://ffl.com:8000/assets/vendor.js:145201:41)
at Class._internalModelForId (http://ffl.com:8000/assets/vendor.js:144337:29)
at Class._pushResourceIdentifier (http://ffl.com:8000/assets/vendor.js:145716:19)
at BelongsToRelationship.updateData (http://ffl.com:8000/assets/vendor.js:142394:36)
at BelongsToRelationship.push (http://ffl.com:8000/assets/vendor.js:142976:14)
at http://ffl.com:8000/assets/vendor.js:145795:20
at http://ffl.com:8000/assets/vendor.js:141943:18
defaultDispatch # ember.debug.js:16905
dispatchError # ember.debug.js:16888
onerrorDefault # ember.debug.js:30389
trigger # ember.debug.js:57833
(anonymous) # ember.debug.js:58717
invoke # ember.debug.js:339
flush # ember.debug.js:407
flush # ember.debug.js:531
end # ember.debug.js:601
run # ember.debug.js:724
join # ember.debug.js:746
run.join # ember.debug.js:21556
hash.success # rest.js:954
fire # jquery.js:3305
fireWith # jquery.js:3435
done # jquery.js:9242
(anonymous) # jquery.js:9484
I checked your issue and repo. The problem was just with comment serializer in Ember.js. It should be:
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
article: { embedded: 'always' },
user: { embedded: 'always' }
}
});
I cloned your project branch refactor-and-upgrade-ember but mirage is not done. So I looked at the code
headTags() {
let article = this.modelFor(this.routeName);
}
This is in routes articles show ,can you try and remove it and try.

Ember data JSON Api adapter set all attributes to undefined

In an application using ember 2.1.0 and ember-data 2.1.0, I have this model :
# app/models/user.js
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr()
});
And this route :
# app/routes/subscriptions/new.js
export default Ember.Route.extend({
model() {
this.store.findRecord('user', 1).then(function(data) {
console.log(data.id)
console.log(data.get('email'))
})
return this.store.find('user', 1);
}
});
I have this adapter :
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({host: 'http://localhost:5000'})
This data is returned by the server :
{"data":{"id":"1","type":"users","attributes":{"email":"test#test.com"}}}
In the console, I have the user id but the email is undefined. In the template, {{model.email}} gives nothing.
I may miss something but it's so simple. Is it my mistake or a bug?
You have to also specify email attribute in model:
export default DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string')
});

ember data 1.13.8 and ember cli mirage confusion

This is my Ember inspector info tab:
I am using ember-cli-mirage and I'm facing issue here.
I am not able to get belongsTo relationship of a model. When I do car.get('user'), I get a promise in result which gets fullfilled but the value is always null.
My user model
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('String'),
car: DS.belongsTo('car',{async: true})
});
My car model
import DS from 'ember-data';
export default DS.Model.extend({
color: DS.attr('String'),
user: DS.belongsTo('user',{async: true})
});
my mirage/config
this.get('/cars',function(db,request) {
var qp = request.queryParams.searchString.toLowerCase();
return {
cars: db.cars.where({'color':qp}),
users: db.users
};
});
I get the list of cars with search color but I don't get the user.
it returns a promise which when fullfilled gives null.
Since I am using ember-data 1.13.8
I tried using this Mirage working with json but then I get error
datum model is not defined error so i guess new json api is not my issue for some reason my ember data uses old json format and original config works.
this.get('/cars', function(db, request) {
return {
data: db.cars.map(attrs => (
{type: 'cars', id: attrs.id, attributes: attrs }
))
};
})
My cars route look like this
model: function(params) {
self = this;
if(!params){
return [];
}
return this.store.findQuery('car',params);
},
I tried
return this.store.findQuery('car',params).then(function(item){
console.log(item.get('user'));
});
but i still got console.log //undefined
I can see user_id in my json returned.
SOLUTION:
found the issue i was saving relationship as user_id = user.id. It should be user=user.id
SOLUTION: found the issue i was saving relationship as user_id = user.id. It should be user=user.id

Ember.js make model of embedded / sideloaded data

To use ember validations I need to make a model of embedded data. I use Ember CLI.
The JSON looks something like this:
{
"endpoint": {
"name": "Name of form",
"form_settings": {
"id": 2,
"setting_one": "Setting 1"
},
"id": 2
}
}
I've made this serializer:
import applicationSerializer from 'closealert-ui/serializers/application';
import DS from 'ember-data';
var endpointSerializer = applicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
endpointFormSettings: {embedded: 'always'}
}
});
export default endpointSerializer;
I've made an endpoint model:
import DS from 'ember-data';
export default DS.Model.extend({
formName: DS.attr('string'),
formSettings: DS.belongsTo('endpointFormSettings'),
});
And I've made an enpoint-form-settings model:
import DS from 'ember-data';
export default DS.Model.extend({
endpoint: DS.belongsTo('endpoint'),
settingOne: DS.attr('string')
});
When I look in the ember inspector the endpointFormSettings model is still empty. What am I missing?