How to update links attribute in ember data dynamically? - ember.js

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?

Related

Creating model with nested objects and arrays in Loopback version LB4

I've just started with Loopback for the first time and I've started with LB4, their newest release. I'm looking to create a model with nested objects and arrays as per my JSON schema to which I followed the documentation which allowed me to create the base values of my schema, but I need to create the fields inside the objects and arrays, but I can't find the documentation or articles to help me understand this...
This is my JSON schema I'm trying to create a LB4 model with:
"socialProfiles": {
"facebook": {
"linked": 1,
"pullData": 1,
"linkID": 4434343,
"profile": "https://www.facebook.com/FBURL",
"registered": {
"date": "2018-05-04T12:41:27.838Z",
"verified": "2018-05-04T12:41:27.838Z",
"by": {
"id": 1,
"user": "USER"
}
}
},
}
Using the LB4 documentation, I can create my main field socialProfiles but I can't find where I go to create my fields inside this object... Here's my LB4 model code
import {Entity, model, property} from '#loopback/repository';
#model()
export class Users extends Entity {
#property({
type: 'object',
})
socialProfiles?: object;
constructor(data?: Partial<Users>) {
super(data)
}
}
How to do this?
If you want to store the object in the model itself (not with a relation), you can create an interface with something like:
export interface ISocialProfile {
"linked": number,
"pullData": number,
"linkID": number,
"profile": string,
"registered": {
"date": Timestamp,
"verified": Timestamp,
"by": {
"id": number,
"user": string
}
}
}
and then in your model, you can just add the type:
socialProfiles?: {[name: string]: ISocialProfile};

Ember Nested Data in JSON Response

I'm having some trouble accessing some nested data in one of my Ember models. Below is the JSON response...
{
"fields": {
"header": {
"name": "header",
"type": "text",
"localize": false,
"options": []
},
"body": {
"name": "body",
"type": "textarea",
"localize": false,
"options": []
}
},
"entries": [
{
"header": "header test",
"body": "body test body test body test",
"_mby": "5a395e8430c2ddoc683600766",
"_by": "5a395e8430c2ddoc683600766",
"_modified": 1513709605,
"_created": 1513709605,
"_id": "5a3960253d578doc735798511"
}
],
"total": 1
}
Here is my current serializer
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
normalizeResponse(store, primaryModelClass, payload, id, requestType)
{
payload = {
entries: payload.entries
};
return this._super(store, primaryModelClass, payload, id, requestType);
}
});
I'm trying to get the Entries in my template. Perhaps I need some help better serializing this with NormalizeResponse? I'm very stumped so please share if you have any ideas!
Thanks!!
The ember-data RESTAdapter expects the JSON to contain keys that correspond to model names and values to be arrays of JSON objects with key-value pairs according to the respective models' attribute-name--attribute-value-type definitions*.
So if you have a model named entry containing header: attr('string'), body: attr('string'), the following JSON should lead to an entry in the store:
{
"entries": [{
"header": "header test",
"body": "body test body test body test",
"id": "5a3960253d578doc735798511"
}],
}
There is a way to convince ember-data to customize the id field name (to accept _id instead of id). The build-in pluralization rules should include the entry->entries pluralization (but I cannot vouch for it).
Any top-level key that does not correspond to a model name should be ignored anyway, so no need to filter it out manually (unless you have models named field or total).
If you then return this.store.findAll('entry') (or query('entry',{/*something*/}) in your route's model hook, you should be able to look over {{#each model as |entry|}} in your controller's template.
(It is good practice to not use model as the model name, but if you want it to be entries, you have to specify that explicitly somewhere, i.e. the controller or the route's setupController method.)
*The point of repeating the name of the model as top-level key in the json response (presumably to an API endpoint of the same name) is that you can include other models if you whish and they will be added to the store as well.

ember-data: Allow sideloaded model to contain embedded records that were just created

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.

Ember 2.0 component request for data

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.

How to get the return data of a save with Ember Data?

I'm using Ember.js with ember-data to make a GUI for a self made API.
I've been following this tutorial to handle authentication but I want to use ember-data instead of custom jQuery requests.
One thing I have to do is to call the API to create a new session, by sending email and password, and the API sends me back an API Key object.
Here is my LoginController handling the loginUser action (it's CoffeeScript) :
App.LoginController = Ember.ObjectController.extend
actions:
loginUser: ->
session = #store.createRecord 'session',
email: #get 'email'
password: #get 'password'
session.save()
Here is the result I get when creating a session:
{
"users": [
{
"id": "525fa0286c696c0b14040000",
"email": "john.doe#mydomain.com",
"first_name": "John",
"surname": "Doe"
}
],
"api_key": {
"id": "526e464c6c696c07d2000000",
"type": "session",
"key": "6b824d6a-a065-4b6f-bb28-5c19389760f8",
"expires_at": "2013-10-28T11:41:08+00:00",
"user_id": "525fa0286c696c0b14040000"
}
}
I have Session, ApiKey and User models. I can create the session, but the thing I don't understand is how to access the return value of the save() method.
I know that my ApiKey and User are loaded somewhere because I get an error after save() if their respective Ember model don't exist but I don't know how to access them.
I've tried to use save() callbacks like then() or didCreate event but there's a lack of documentation about arguments passed to these callbacks and how to use them.
Ember.js 1.1.2
Ember Data 1.0.0.beta.3
EDIT:
I've tried to create an actuel Session model on my API, resulting in this JSON output:
{
"api_keys": [
{
"id": "526f69526c696c07d2110000",
"type": "session",
"key": "4c26af37-2b21-49c2-aef5-5850a396da0b",
"expires_at": "2013-10-29T08:22:50+00:00",
"user_id": "525fa0286c696c0b14040000"
}
],
"users": [
{
"id": "525fa0286c696c0b14040000",
"email": "john.doe#coreye.fr",
"first_name": "John",
"surname": "Doe"
}
],
"session": {
"id": "526f6e666c696c18c0010000",
"api_key_id": "526f69526c696c07d2110000"
}
}
(note the root element is now session)
It doesn't work better because now my save action leads to the following error (not in the console but then points to error callback):
Object function () { [...] } has no method 'eachTransformedAttribute'
I get this error, the relation between Session and ApiKey being declared in Ember Data models or not...
Your second example JSON looks better: since you are saving a Session, I would expect a session node in the response and other models to be side loaded. You can access the saved session after it's saved by using a promise callback:
session.save().then (savedSession) =>
console.log savedSession.api_key.key
Since you have _id relationship keys in your JSON, I assume you are using the ActiveModel adapter and its default serializer:
App.ApplicationAdapter = DS.ActiveModelAdapter.extend()