javascriptember.jsember-datajson-api

Ember 3.25 BelongsTo not sideloading


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.

enter image description here


Solution

  • 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 :)