I am trying to sideload relationship data from one API call. I have a my two models setup like so:
Contest Model (child, belongsTo):
import Model, { attr, belongsTo } from '@ember-data/model';
export default class ContestModel extends Model {
@attr('date') createdAt;
@attr('string') description;
@belongsTo('brand', { inverse: 'contests' }) brand;
}
Brand Model (parent, hasMany):
import Model, { attr, hasMany } from '@ember-data/model';
export default class BrandModel extends Model {
@attr('date') createdAt;
@attr('string') name;
@hasMany('contest') contests;
}
I'm fetching via this line:
this.store.findRecord('contest', params.contest_id, { include: 'brand' });
This is the returned API payload:
{
"data": {
"type": "contest",
"id": 1,
"attributes": {
"body_json": [
{
"question": "what time is it?",
"answers": ["1PM", "2PM", "3PM", "4PM"]
},
{
"question": "which collection is this artwork from?",
"answers": ["botanical garden collection", "ghibli collection", "adventure collection", "swag collection"]
}
],
"created_at": "2021-05-23 18:00:00 -0700",
"description": "a good description goes here"
},
"relationships": {
"brand": {
"links": {
"self": "http://example.com/contests/2/relationships/brand" // not sure what this does
},
"data": { "type": "brand", "id": 2 }
}
},
"links": {
"self": "http://example.com/contests/2" // not sure how this is useful
},
"included": [
{
"id": 2,
"type": "brand",
"attributes": {
"created_at": "2021-05-23 20:00:00 -0700",
"name": "aloha vibe"
}
}
]
}
}
The issue here is that calling myContest.brand
returns a Proxy object just like in this SO post.
Is my API payload incorrect or is something misconfigured for my models? Or something else? I'm on Ember 3.25.3
Update from comments: When I add async: false
to the Ember Data query, I get an error after this line https://github.com/emberjs/data/blob/v3.25.0/packages/store/addon/-private/system/model/internal-model.ts#L705 due to toReturn.isEmpty
being true. Did I not configure my API payload? Not sure what is wrong. It seems neither createdAt
nor name
is populated.
Found the bug! The data payload needs to be in this format:
{
"data": {
"type": "contest",
"id": 1,
"attributes": {
"body_json": [
{
"question": "what time is it?",
"answers": ["1PM", "2PM", "3PM", "4PM"]
},
{
"question": "which collection is this artwork from?",
"answers": ["botanical garden collection", "ghibli collection", "adventure collection", "swag collection"]
}
],
"created_at": "2021-05-23 18:00:00 -0700",
"description": "a good description goes here"
},
"relationships": {
"brand": {
"links": {
"self": "http://example.com/brands/2"
},
"data": { "type": "brand", "id": 2 }
}
},
"links": {
"self": "http://example.com/contests/2"
}
},
"included": [
{
"id": 2,
"type": "brand",
"attributes": {
"created_at": "2021-05-23 20:00:00 -0700",
"name": "aloha vibe"
}
}
]
}
I had nested the included
within the data
section but it should be at the top level with the data
section. Now things are properly sideloaded and no extra API call is made :)