Reputation: 3597
While trying to build an Ember.js sample application, to call a REST Api and display results. I was able to call, fetch and display the results. In the component I am reading through the json response results.
How can I map the response data
to a pre-defined model and use that in the component instead? I could not find relevant docs at https://guides.emberjs.com/release/models/defining-models/ or https://guides.emberjs.com/release/in-depth-topics/making-api-requests/#toc_where-to-make-api-requests
Code details:
export default class UserModel extends Model {
@attr('string') id;
@attr('string') firstname;
@attr('string') lastname;
@attr('string') email;
@attr('string') avatar;
}
export default class UsersRoute extends Route {
async model() {
let response = await fetch('https://reqres.in/api/users');
let data = await response.json();
return data.data;
}
}
<UserList
@title="List of Users"
@users={{@model}}
/>
{{#each @users as |user|}}
<tr>
<td>{{user.id}}</td>
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
<td>{{user.email}}</td>
</tr>
{{/each}}
Upvotes: 0
Views: 838
Reputation: 365
Generate a user model:
ember g model user
import Model, { attr } from '@ember-data/model';
export default class UserModel extends Model {
@attr('string') email;
@attr('string') firstName;
@attr('string') lastName;
@attr('string') avatar;
}
Generate an application adapter and serializer:
ember g adapter application
ember g serializer application
Add your API URL to the adapter:
import JSONAPIAdapter from '@ember-data/adapter/json-api';
export default class ApplicationAdapter extends JSONAPIAdapter {
host = 'https://reqres.in/api'; // the `users` part of the path is autogenerated based on the model name
}
Update the serializer:
import JSONSerializer from '@ember-data/serializer/json'; // note that this is not the default serializer, JSONAPISerializer
import { underscore } from '@ember/string';
export default class ApplicationSerializer extends JSONSerializer {
// specify underscore-formatted keys
keyForAttribute(attr) {
return underscore(attr);
}
// use the `data` property in the payload as the serializable response
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
payload = payload.data;
return super.normalizeResponse(store, primaryModelClass, payload, id, requestType);
}
}
Update your route to use Ember Data methods instead of raw fetch
:
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class UsersRoute extends Route {
@service store;
model() {
return this.store.findAll('user');
}
}
And finally you can then use the data (using camelcase-formatted attributes):
{{#each @users as |user|}}
<tr>
<td>{{user.id}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.email}}</td>
</tr>
{{/each}}
Upvotes: 2