I am trying to create an organisations-table component, which will display a list of organisations, and the user for which each organisation belongs. I pass the model for the organisations into the component via an organisations.hbs template, which results in the following response from the server:
{
"organisations": [
{
"id": 0,
"name": "Org0",
"user": 1
},
{
"id": 1,
"name": "Org1",
"user": 2
},
{
"id": 2,
"name": "Org2",
"user": 2
}
]
}
In order to display the username for each user, the component then makes its own call to the server querying against the id for each of the users.
Is this the correct approach? My understanding is that components are supposed to be isolated by design, only aware of the data passed into them, but in this example, the component is sending its own requests to the server for the additional data.
I have created this ember twiddle to hopefully give an idea of the structure of the app (comments welcome!).
Thanks in advance
The component itself has nothing to do with the calls, { async: true } means that the relationship won't be fetched unless it is "needed".
Needed in this case being the organisation.user.username in your component's template.
Keep in mind that model in your case is an array of DS.Model objects that have relationships.
Related
I currently have a response like so from my API:
{
"data": [{
"attributes": {
"customer_name": "The Name",
},
"id": 1,
"relationships": {
"tasks": {
"data": [{
"attributes": {
"name": "The task",
},
]
}
},
"type": "customer"
}
]
}
And Ember loads the model correctly. However, when I try and consume the computed property the relationship creates, Ember initiates an OPTIONS and subsequent GET request for each item in the relationship.
I haven't worked with these kinds of relationships before so this may be the expected behaviour but I'm a bit confused.
If it is going to do a request for each one, why bother sending the items as part of the original model via a relationship at all? Why not just do a normal model retrieval which would probably be much quicker.
It seems really wasteful so I suspect I'm not handling or understanding something correctly, I'd appreciate any insight.
This is expected behavior for what you are doing (accessing a hasMany relationship). In your example, the tasks do not exist in Ember Data's store so when trying to access them Ember Data is smart enough to fetch them for you from your API. In doing so, it sends out the OPTIONS and GET requests to retrieve them. The OPTIONS request is simply a preflight request.
If you wanted to work with this particular model and its tasks (or other hasMany relationship models) without making so many network requests, you could fetch both simultaneously by requesting them with an include assuming you're using an adapter that allows it (i.e., supports the JSON API spec) and your API does too:
// for example, fetching a post with its comments (hasMany relationship)
this.store.findRecord('post', params.post_id, { include: 'comments' } );
Doing so should return the model and its tasks in one network request. For further reading, I'd checkout Ember's guide on Relationships.
Good day,
Does removing of links.related on my JSON response will affect any Ember-Data relationship fetching?
relationships": {
"comments": {
"links": {
"related": "http://localhost:3099/api/v1/articles/1/comments"
},
"data": [
{
"type": "comments",
"id": 1
},
{
"type": "comments",
"id": 2
},
{ ... More comments here ... }
]
}
}
I've read this article : https://thejsguy.com/2016/02/21/handling-nested-resources-in-ember-data.html and this points me to Ember data uses those links internally to fetch the related data so I won't have to access those URLs and make requests to them. I need more concrete opinion before we make any changes to our API.
The related link is used when you don't specify data. Specifying both is redundant.
An example use-case:
You load a lit of blog posts, each has many comments. You don't want to load the comments yet tho. So you specify a relationship with a related link and no data. When the user clicks on the blog post you show the comments. Ember then will automatically load the comments from the specified link.
I’m running into an issue with the REST Adapter/Serializer and EmbeddedRecordsMixin, specifically my app needs to be able to sideload an model’s parent record in create/POST responses, and that parent model contains the child record embedded in a hasMany array. This is resulting in “You cannot update the id index of an InternalModel once set.” errors. heres a simplified version of the JSON structure my api is returning:
// POST /child-model response
{
"childModel": {
"id": 1,
"foo": "Bar"
},
"parentModel": {
"id": 2,
"children": [
{
"id": 1,
"foo": "Bar"
}
]
}
}
Is there any way to allow this type of response? Essentially I want ember-data to just treat the embedded child record as just an "update" to the record that was just created, where it is just using it to make the association between it and the parent record.
I am trying to use the JSON API Adapter with ember-cli 2.5.1 , but I'm having a bit of trouble.
I have a todo-list.js model, which has a "hasMany" relationship to todo-list-item.js. Getting the todo-list, the server returns this:
{
"links": {
"self": "http://localhost:4200/service/v1/todolists/b-tlst-af69786c-cbaf-4df9-a4a3-d8232677006a"
},
"data": {
"type": "todo-list",
"id": "b-tlst-af69786c-cbaf-4df9-a4a3-d8232677006a",
"attributes": {
"name": "b1-TodoList",
"created-on": 1468474962458,
"modified-on": 1468474962458
},
"relationships": {
"todolistitems": {
"data": {
"type": "todo-list-item",
"id": "b-todo-b5e3c146-d93a-4f97-8540-875bbcd156ca"
}
}
}
}
}
If there had been two TodoListItem children instead of one, the value of that "data" key would have been an array, rather than an object.
After receiving this, I was expecting the Ember Chrome plug-in's "Data" tab to show 1 TodoList and 1 child TodoListItem. Instead, it shows 1 TodoList and 0 TodoListItems.
I note from the Network tab that the browser never makes a request to get the items listed in the "data" section of the response.
Is the relationships section above correct and sufficient?
It turns out to have been caused by promise misunderstandings on the client side, and additionally, on the server I had to put dashes in the "relationships" key (i.e. "todo-list-items") and make the value of "data" an array.
To load async relationship ember data payload usually contains links attribute.
{
"post": {
"id": 1,
"title": "Progressive Enhancement is Dead",
"links": {
"user": "/people/tomdale"
},
},
}
In my case application have to create link itself due to the fact that it operate on date and time selected by the user. Link to the relationship is not fixed. It there any way to change model link attribute on runtime or do I really need to create whole relationship manually using Ember.$.ajax?
You can create a serializer to customize the links field. Example:
App.PostSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload) {
payload.links = {
"user": getMyLink(payload.links, payload.id)
};
return payload;
}
});
where getMyLink is your custom function.
Does this address your problem?