How to set nested object in model


#1

Hi guys, I have some messed up situation. So i have tag model which has following fields and it’s responses from backend. Now when i try to update or create new data it gives me an error:

Cannot call set with ‘feature’ on an undefined object."

Cannot call set with ‘detail’ on an undefined object."

What i have is tag-form component and edit, new routes. So other title is fine but show field, and images fields are nested objects. I think error triggers that’s why? how can i fix it. here is model

import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr('string'),
  show: DS.attr(),
  images: DS.attr(),
});

backend response is:

{    
    "title": "Tasty",
    "images": {
        "thumb": "https://placehold.it/200/200",
        "cover": "https://placehold.it/300/500"
    },
    "show": {
       "detail": true,
       "feature": true
    }
}

edit route:

//route.js
model(param) {
  return this.store.findRecord('tag', params.id)
}

//template
{{tag-form tag=model isUpdate=true}}

new route:

//route.js
model() {
  return this.store.createRecord('tag')
}

//template
{{tag-form model=model}}

Now my tag-form is:

<form id="myForm" data-abide novalidate {{action "tagAction" model on='submit'}} >
  {{input value=model.title}}
  {{input value=model.images.thumb}}
  {{input value=model.images.thumb}}
  {{input value=model.show.detail}}
  {{input value=model.show.feature}}
</form>

#2

looks like after you have created record, show and image aren’t objects. Try adding defaults to both of them in model, and set as plain objects


#3

How to add defaults to them? Like ember don’t allow nested objects in model field right? is it possible to define like this?

  show: DS.attr(
    {
      detail: DS.attr('boolean')
    }
  ),

#4

hey, sorry for late response, check here https://emberjs.com/api/ember-data/2.16/classes/DS.Model/methods?anchor=changedAttributes there’s default value in example.

" is it possible to define like this?" - no it’s not But you can set object in models property, just pass nothing to attr. LIke DS.attr().