1

I have a JSON-Api backend and I can't find the good way to deal with inheritance objects, because the Route ressource name is the parent Class but the "type" attribute in the payload correspond to the child class. Example of payload (GET /api/pets):

{
    "data": [
        {
            "id": "1",
            "type": "cat",
            "attributes": {
                "name": "Tom"
            }
        },
        {
            "id": "2",
            "type": "dog",
            "attributes": {
                "name": "Max"
        }
    ]
}

Now, I load it with a Route:

# app/routes/pets.js
import Route from '@ember/routing/route';

export default Route.extend({
  model() {
    return this.get('store').findAll('pet');
  }
});

Models:

# app/models/pet.js
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string')
});

# app/models/cat.js
import DS from 'ember-data';
import Pet from './pet';

export default Pet.extend({
});

# app/models/dog.js
import DS from 'ember-data';
import Pet from './pet';

export default Pet.extend({
});

And finally, I want to display them on a simple page:

# app/templates/devices.hbs
<h3>Pets list</h3>

{{#each model as |pet|}}
  <h4>{{pet.name}}</h4>
{{/each}}

The objects are well loaded by the Route (I saw them with the Ember inspector), but there are not Pet objects, so they are not rendered. At this point, I don't know how to deal with that, without changing the api structure.

NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352
Dainii
  • 43
  • 3

1 Answers1

2

This is going to take a little work, but probably won't be too bad.

First you need to create a Pet serializer: ember generate serializer pet.

Then you can override the normalize hook to return a different model based on the attributes in the response:

https://emberjs.com/api/ember-data/3.3/classes/DS.JSONAPISerializer/methods/normalize?anchor=normalize

Or if there aren't any actual differences between dogs/cats, you could just move the type into the attributes field in the same normalize hook.

  • I've created a `Pet` serializer, but apparently, it applies only on `Pet` objects. But, if I create a `Cat` serializer, I can successfully change the *type* to `Pet`, but this means to create a serializer for each child class I have to deal with. – Dainii Aug 17 '18 at 08:37
  • You could create one serializer for 'application' and reuse that or create one and extend it from the specific serializers. – knownasilya Aug 17 '18 at 15:38