Sumit Sumit - 11 days ago 7
Javascript Question

Ember not persisting belongsTo data

I am using Ember 2.4.6 and JSONApiAdapter of Ember for getting and sending data to the node servers.

I have the following Tags model:

import DS from 'ember-data';

export default DS.Model.extend({
label: DS.attr('string'),
isRoot: DS.attr('boolean', {defaultValue: false'}),
parent: DS.belongsTo('tag') //belongs to self type
});


The logic here is that a user can enter multiple sub tags for a given root tag. And to save the sub tags and the root tags I am using a save method from tag service. The save method from tag service is as below

import Ember from 'ember';

export default Ember.Service.extend({

//Some other code

save: function(parent, children){
return parent.save().then(response => {
return children.map(tag => {
tag.set('parent', response);
return tag.save();
});
});
}
});


Now the problem here is that when I have say five subtags for the root tag, then the relationship is getting persisted only for the last tag i.e. the fifth tag.

I have created five tags say
one
,
two
,
three
,
four
and
five
for the
root
parent tag. Then when the save method is called from the tag service then ideally the following data should be going to the servers.

{data: {id: 1, type: 'tags', attributes: {label: "root", "is-root": true}, relationships: {parent: {data: null}}}}
{data: {id: 2, type: 'tags', attributes: {label: "one", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}
{data: {id: 3, type: 'tags', attributes: {label: "two", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}
{data: {id: 4, type: 'tags', attributes: {label: "three", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}
{data: {id: 5, type: 'tags', attributes: {label: "four", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}
{data: {id: 6, type: 'tags', attributes: {label: "five", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}


but instead the following information is going to the server

{data: {id: 1, type: 'tags', attributes: {label: "root", "is-root": true}, relationships: {parent: {data: null}}}}
{data: {id: 2, type: 'tags', attributes: {label: "one", "is-root": false}, relationships: {parent: {data: null}}}}
{data: {id: 3, type: 'tags', attributes: {label: "two", "is-root": false}, relationships: {parent: {data: null}}}}
{data: {id: 4, type: 'tags', attributes: {label: "three", "is-root": false}, relationships: {parent: {data: null}}}}
{data: {id: 5, type: 'tags', attributes: {label: "four", "is-root": false}, relationships: {parent: {data: null}}}}
{data: {id: 6, type: 'tags', attributes: {label: "five", "is-root": false}, relationships: {parent: {data: {id: 1, type: "tags"}}}}}


The belongsTo information is only being sent for the last tag, and for all the other tags, the parent data is getting missed.

Not able to exactly understand why this is happening. Please suggest what I am doing wrong here.

Answer

In your Tags model, try this:

import DS from 'ember-data';

export default DS.Model.extend({
  label: DS.attr('string'),
  isRoot: DS.attr('boolean', {defaultValue: false}),
  parent: DS.belongsTo('tag', {inverse: null})
});

You can get more information about reflexive relationships here: https://guides.emberjs.com/v2.9.0/models/relationships/#toc_reflexive-relations

From the page:

When you want to define a reflexive relation (a model that has a relationship to itself), you must explicitly define the inverse relationship. If there is no inverse relationship then you can set the inverse to null.