Potential bug in store when hydrating find results

What is the following line doing: discourse/app/assets/javascripts/discourse/models/store.js.es6
?

return this._hydrate(type, result[Ember.String.underscore(type)], result);

In particular, why is the second argument of the _hydrate() method not the result object? Usually, the second argument for this method is the record object that is saved to/retrieved from the store.

Here, when I’m trying to find a record by ID, I will always run into this line:

if (!obj) {
  throw new Error("Can't hydrate " + type + " of `null`");
}

That’s because _hydrate() will be called with result[Ember.String.underscore(type)]. Since my record doesn’t have a property named like the type, that’s always undefined.

Is that a bug?

4 Likes

We require when returning data from the server that the object is not the root of the JSON object. For example instead of:

{ "id": 123, "name": "robin"} it should be {"person": {"id": 123, name: "robin"} }

This is used for cross-referencing records. For example a JSON payload might include multiple relationships and the store will wire them up together.

If you have no control over your server API, you can create a new adapter to transform the returned JSON into the format our code requires.

7 Likes

@eviltrout If I understand this correctly, for an endpoint plugin-route, the method this.store.find('plugin-route') would return a response with a plugin_route property (singular) in the responseJson property, but the method this.store.findAll('plugin-route') would return a response with a plugin_routes property (plural) in the responseJson property?

Likewise, sending a request for /persons, a response object with a property persons in responseJson is expected, correct?

{
  "persons": []
}
2 Likes

Yes that is the idea. You can review a bunch of examples in our test suite:

6 Likes