I'm trying to use ember data with REST API
from server. The project is quiet simple and works fine with Fetch API
, but i would like to implement the same result using Ember data
and understand it's principles. I could not use ember twiddle
with this configuration. Below will be the main parts of the project. It was made by Ember CLI
version 4.0.1.
The JSON
responce from url http://localhost:3000/api/v1/items
looks like:
[
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
},
{
"id": 2,
"name": "Item 2",
"description": "22222",
"created_at": "2022-01-07T11:43:29.787Z",
"updated_at": "2022-01-07T11:43:29.787Z"
},
{
"id": 3,
"name": "Item 3",
"description": "33333",
"created_at": "2022-01-07T11:43:37.885Z",
"updated_at": "2022-01-07T11:43:37.885Z"
}
]
The responce from a single item request such as http://localhost:3000/api/v1/items/1
:
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
}
app/models/item.js
:
import Model, { attr } from '@ember-data/model';
export default class ItemModel extends Model {
@attr name;
@attr description;
}
app/routes/items.js
:
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ItemsRoute extends Route {
@service store;
async model() {
return this.store.findAll('item');
}
}
app/routes/item.js
:
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ItemRoute extends Route {
@service store;
async model(params) {
return this.store.findRecord('item', params.id);
}
}
app/templates/items.hbs
:
{{#each @model as |item|}}
<LinkTo @route='item' @model={{item}}>{{item.name}}</LinkTo>
{{/each}}
app/adapters/application.js
:
import RESTAdapter from '@ember-data/adapter/rest';
export default class ItemAdapter extends RESTAdapter {
host = 'http://localhost:3000';
namespace = 'api/v1';
buildURL(...args) {
return `${super.buildURL(...args)}.json`;
}
}
app/serializers/application.js
:
import RESTSerializer from '@ember-data/serializer/rest';
export default class ItemSerializer extends RESTSerializer {}
app/router.js
:
import EmberRouter from '@ember/routing/router';
import config from 'dist/config/environment';
export default class Router extends EmberRouter {
location = config.locationType;
rootURL = config.rootURL;
}
Router.map(function () {
this.route('items');
this.route('item', { path: '/:id' });
});
When I move to route /items
on the ember client, the following error appears in the console:
WARNING: Encountered "0" in payload, but no model was found for model name "0" (resolved model name using <dist@serializer:item::constructor>.modelNameFromPayloadKey("0"))
And the same errors for "1" and "2". The template doesn't render links in the each
loop.
Probably, there are some features in Ember data
with REST API
, and I would really like to figure it out. Thanks for attention!
I believe you have this issue because your data is not in the RESTSerializer
format but rather in the JSONSerializer
one:
the JSONSerializer expects the response to be a JSON object that looks similar to this
{
"id": "1",
"title": "Rails is omakase",
"tag": "rails",
"comments": ["1", "2"]
}
So i guess you should just use this one.
If for any reason you wanna keep the RESTSerializer
you should return your data similar to this format:
{
"item":
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
}
}
or for a list
{
"items": [
{
"id": 1,
"name": "Item 1",
"description": "12345",
"created_at": "2022-01-07T11:43:21.755Z",
"updated_at": "2022-01-07T11:43:21.755Z"
},
...
]