Showing posts with label ember-data. Show all posts
Showing posts with label ember-data. Show all posts

Sunday, April 2, 2017

How can I pass IDs for hasMany relationship using store.createRecord()?

Leave a Comment

Assume I have the following models:

// customer.js DS.Model.extend({   products: DS.hasMany('product') });  // product.js DS.Model.extend({  customer: DS.belongsTo('customer')   }); 

And I need to create a customer with a list of products by IDs(which are not yet loaded from backend), something along the lines of this:

this.get('store').createRecord('customer', {products: [1, 2, 3]});   

But this fails as the store expects the products to be an Array of DS.Model.

How can I create a record with its associations provided by IDs?

2 Answers

Answers 1

Error while processing route: index Assertion Failed: All elements of a hasMany relationship must be instances of DS.Model, you passed [1,2,3] Error

As the error states that You need to pass instance of DS.Model but you can only create instance using createRecord so you might need to do some thing like below,

    let product1 = this.store.createRecord('product',{customer:1});     let product2 = this.store.createRecord('product',{customer:2});         return this.get('store').createRecord('customer', {products:[product1,product2]}); 

Answers 2

If related records do not exist then you cannot create them on the fly just using IDs. However, you could do something like this:

let customer = this.store.createRecord('customer', {}); customer.get('products').then(function() {     customer.get('products').addObject(this.store.createRecord('product', {/* ... */})); }); 
Read More

Tuesday, April 26, 2016

Ember Data async usage of hasMany

Leave a Comment

I have nested route with a hasMany relationship. I have declared the model this way:

export default DS.Model.extend({     label: DS.attr('string'),     archetyp: DS.attr('number'),     searchable: DS.attr('boolean'),     showInList: DS.attr('boolean'),     managedItem: DS.belongsTo('managedItem') }); 

And the corresponding model looks like so:

export default DS.Model.extend({   title: DS.attr('string'),   description: DS.attr('string'),   logo: DS.attr('string'),   logo_alt: DS.attr('string'),   fields: DS.hasMany('field', {async: true}) }); 

And in the fields/index route I want to load the fields from the server. Therefore I have hooked into the model hook.

export default Ember.Route.extend({   model() {     let fields = this.modelFor('managedItems/edit').get('fields');     if (fields.get('isFulfilled')) {       fields.reload();     }     return fields;   } }); 

But I can't see any network request and if I try to console.log(field) I see that the model is empty. What do I miss here?

EDIT: As an additional information: if I just call this.modelFor("managedItems/edit") and ask for some properties of the model object, I always get undefined except for the isLoaded property...
Here is the Router:

Router.map(function() {   this.route('managedItems', {   }, function() {     this.route('new');     this.route('show', {path: ':managedItem_id'});     this.route('edit', {path: ':managedItem_id/edit' },       function() {            this.route('fields', { resetNamespace: true }, function () {          });       });     }); }); 

2 Answers

Answers 1

Your model hook in the route should return a Promise in any case. Have you tried something like:

export default Ember.Route.extend({     model() {         return this.modelFor('managedItems/edit').get('fields');     } }); 

Answers 2

Change managedItems/edit to managedItems.edit as below:

let fields = this.modelFor('managedItems.edit').get('fields'); 

"managedItems/edit" is the path of the route (if you don't overwrite it). The name of the route is "managedItems.edit".

Also, fields.reload(); is returning a promise. I'm not sure but IMO the correct model hook function will be like that:

export default Ember.Route.extend({   model() {     let fields = this.modelFor('managedItems.edit').get('fields');     if (fields.get('isFulfilled')) {       return fields.reload(); //You should return this promise.     }     return fields;   } }); 
Read More