0
votes

Is it obvious to anyone why my 'product' data is not side-loading? I am seeing separate API requests to /product for each cart-item. My cart-item model is:

export default Model.extend({
    cart: belongsTo('cart'),
    product: belongsTo('product', { async: true }),
    skuid: attr('string'),
    quantity: attr('number'),
    personalization: attr(''),
    variantCodes: attr(''),
    variantData: attr(''),
    prices: attr('')
});

An example API payload is (I am using RESTAdapter):

{
    "cart-items": [
        {
            "cart": "0048f8cc-ef50-11e7-8337-76502ffc62f3",
            "id": "ROVE949352B",
            "personalization": [],
            "prices": {
                "price": 74.95,
                "totalPrice": 74.95
            },
            "product": 4464,
            "quantity": 1,
            "skuid": "ROVE949352B",
            "variantCodes": [],
            "variantData": []
        },
        {
            "cart": "0048f8cc-ef50-11e7-8337-76502ffc62f3",
            "id": "BLK4226",
            "personalization": [],
            "prices": {
                "origprice": 0,
                "price": 60,
                "totalPrice": 60
            },
            "product": 4502,
            "quantity": 1,
            "skuid": "BLK4226",
            "variantCodes": [],
            "variantData": []
        }
    ],
    "products": [
        {
            "id": 4464,
            "images": {
                "image": "tristan-irish-watch.jpg",
            },
            "name": "Watch - Gold Plated Watch",
            "prices": {
                "price": 74.95
            },
            "skuid": "ROVE949352B"
        },
        {
            "id": 4502,
            "images": {
                "image": "BLK4226.jpg",
            },
            "name": "Serving Bowl",
            "prices": {
                "origprice": 0,
                "price": 60
            }
            "skuid": "BLK4226"
        }
    ]
}

The relationship works fine, it's just resulting in separate requests. I tried async: false but ember is complaining that the data is not there:

Assertion Failed: You looked up the 'product' relationship on a 'cart-item' with id ROVE949352B but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async 

I've also tried using "includes" in the route model hook like:

model() {
    return this.get('store').findAll('cart-item', { include: 'products' });
}

Any help appreciated!

UPDATE

I am using RESTAdapter (not JSON:API) and I'm side-loading data successfully with other models. I can’t for the life of me figure out what’s different with this one. For example, this is a very similar one, saveditem:

export default Model.extend({
    user: belongsTo('user'),
    product: belongsTo('product', { async: true }),
    dateAdded: attr('number')
});

The payload from the API (which sideloads the products) looks like this:

{
    "saveditems": [
        {
            "dateAdded": 1514914371,
            "id": "f51bf2b8-efe2-11e7-8337-76502ffc62f3",
            "product": 4502,
            "user": "me"
        },
        {
            "dateAdded": 1514440889,
            "id": "8c3a7f96-eb94-11e7-8337-76502ffc62f3",
            "product": 1312,
            "user": "me"
        }
    ],
    "products": [
        {
            "id": 4502,
            "images": {
                "image": "BLK4226.jpg",
            },
            "name": "Serving Bowl",
            "prices": {
                "origprice": 0,
                "price": 60
            },
            "skuid": "BLK4226"
        },
        {
            "id": 1312,
            "images": {
                "image": "GC689.jpg",
            },
            "name": "Classic Cross",
            "prices": {
                "price": 29.95
            },
            "skuid": "JDSGC689GCB"
        }
    ]
}

Sideloading works great on that - no extra API calls. Stumped.

2

2 Answers

0
votes

async: true means to lookup them up separately (literally it means get the data asynchronously) so that will give you separate requests.

So you want async:false

Eyeballing your packets, I'd expect the property on the cart-item to be called product_id, not product. That may fix it.

Failing that I'd start digging into the Ember inspector to look into what data Ember thinks it's loading.

0
votes

Your relationship is called product, but the in the include you're referencing products. Because you're specifying the name of a relationship, the plurality matters. (My Ruby on Rails backend will throw an error if I use the wrong relationship plurality - your experience could vary depending on your backend implementation.)

See if this fixes your issue:

model() {
    return this.get('store').findAll('cart-item', { include: 'product' });
}