Edited as I narrowed down issues....
I'm working on an app that is taking in an API - data as JSON. It is an array of groups, with "name", "id", and other such elements.
{
"status": "success",
"data": {
"groups": [
{
"id": 7100,
"name": "Test 12345",
"kind": "floor",
"parent_group_id": 7000,
"controlled_device_type_count": {},
"is_top_level": true
}
]
}}
I also have a livestream websocket - data as JSON stream. It should update the elements referenced in the first API. The two only share "id".
Livestream:
{
"group":{
"usage":{
"10":1,
"20":0,
"30":2,
"40":2
},
"last_change":"2014-03-24T05:56:10Z",
"id":7954
}}
**Updated...**My IndexRoute:
App.ApplicationAdapter = DS.RESTAdapter.extend({
extractArray: function(store, type, payload, id, requestType) {
payload = payload.data;
return this._super(store, type, payload, id, requestType);
}
});
App.IndexRoute = Ember.Route.extend({
sortProperties: ['id'],
sortAscending: true,
beforeModel: function() {
var socket = window.io.connect('http://localhost:8887');
var self = this;
socket.on('group_live_stream', function(data){
var dataObj = JSON.parse(data);
self.store.push('group',dataObj.group);
});
},
actions: {
toggleMenu: function() {
this.controller.toggleProperty('menuVisible');
this.controller.pushBody();
} },
activate: function() {
var self = this;
$.getJSON('http://localhost:3000/api/groups/top?subscribe=true').then(function(data) {
self.store.pushMany('group', data.data.groups);
});
},
model: function() {
return this.store.all('group');
}
});
Updated:
So now I see the livestream coming through - and for a brief, immediate second - I see the API data (group name) and then it disappears. I'm thinking it's because I'm just "pushMany"-ing records and deleting old ones instead of updating. I've heard/read that pushPayload might be my solution....but I can't figure it out. At all (and when I put it in, I just get an error: "Uncaught Error: No model was found for '0' " Help?!
Any thoughts?
Thanks so much!
ptep
Your API's payload is not in the format that ember-data expects (it looks for your payload in the root of your JSON by default). You'll need to override extractArray (and likely extractSingle) on your ApplicationAdapter something like this:
ApplicationAdapter = DS.RESTAdapter.extend({
extractArray: function(store, type, payload, id, requestType) {
payload = payload.data;
return this._super(store, type, payload, id, requestType);
}
});
Related
I have some problem with get data from storage.
Isset model orders:
import DS from 'ember-data';
export default DS.Model.extend({
test: DS.hasMany('dealer-status'),
});
adapter (its is test data). I havn't normolize responce and i add params to data for normalize. It is implementation will be in serialize :
export default DS.JSONAPIAdapter.extend({
service: Ember.inject.service('admin.auth'),
query(store, type, query) {
var service = this.get('service');
return new Ember.RSVP.Promise(function (resolve, reject) {
service.fetch(query).subscribe(
res => {
var data = {
"data": [{
"type": "user",
"id": "1",
"attributes": {
test: 'test'
}
}]
};
resolve(data);
},
err => {
reject(err);
});
});
}
});
The router:
model() {
return this.get('store').query('orders', {}).then(res => {
console.log(res.get('test')); //undefined
console.log(res.objectsAt(0)); //undefined
})
In router I find by query, but i can't get param test. In Promise res.get('test') return undefined.
Why i get undefined in promise? How fix it?
Because in your order model you don't have attribute test. It's a hasMany relationship. Look into json API documentation about relationships in resource objects for more details.
I can't seem to get Ember Data to work with my API format. Right now my API is like so:
{
data: [
{
id: 1,
name: "Some Company",
primary_contact: "Bob Smith"
},
{
id: 2,
name: "Another Company",
primary_contact: "Bob Smith"
},
]
}
I know that Ember wants the key to be organizations rather then data but that is just not possible. I've been trying to get it working with a serializer, and I don't know if I'm even on the right track. Here is what I currently have.
export default DS.RESTSerializer.extend({
normalizeResponse: function(store, primaryModelClass, payload, id, requestType) {
var pluralTypeKey = Ember.String.pluralize(requestType.typeKey);
payload[pluralTypeKey] = payload['data'];
delete payload['data'];
return this._super(store, primaryModelClass, payload, id, requestType);
}
Any help would be GREATLY appreciated!
Use primaryModelClass.modelName instead requestType.
requestType is just string like 'findAll', 'findRecord' and etc.
export default DS.RESTSerializer.extend({
normalizeResponse: function(store, primaryModelClass, payload, id, requestType) {
var pluralTypeKey = Ember.String.pluralize(primaryModelClass.modelName);
payload[pluralTypeKey] = payload['data'];
delete payload['data'];
return this._super(store, primaryModelClass, payload, id, requestType);
}
Working jsbin: http://emberjs.jsbin.com/weyuwixoli/edit?js,output
Is this possible? I know I can do:
this.store.find('model', 1)
but that's not what I want. I would like to retrieve the json in this format: (working if I retrieve it in the route like this ):
App.OptionsRoute = Ember.Route.extend({
model: function () {
return {
"options":{
"id": "1",
"headline": "A Headline",
"results": [
{
"id": "1",
"title": 'Option 1',
},
{
"id": "2",
"title": "Option 2"
}
]
}
};
}
});
options model:
App.Options = DS.Model.extend({
headline: DS.attr(),
results: DS.attr()
});
options.hbs
<h5>{{options.headline}}</h5>
{{#each item in options.results}}
<h5>{{item.title}}</h5>
{{/each}}
I am using the RESTAdapter. And that is the only model that will be retrieved on that route. I would like to be able to use ember-data, but store.find expects an array.
You're missing a point here. First of all you're using bad format for your response. You need custom serializer. You can also use a bit more dirty workaround like this(but it works). Route:
App.OptionsRoute = Ember.Route.extend({
model: function() {
that = this;
return new Promise(function (resolve, reject) {
url = that.store.adapterFor('option').buildURL('option');
Ember.$.getJSON(url).then(function (json) {
body = json.options;
correct = {
options: [
body
]
};
that.store.pushPayload('option', correct);
resolve(that.store.all('option').get('firstObject'));
});
});
}
});
Template:
<h5>{{model.headline}}</h5>
{{#each item in model.results}}
<h5>{{item.title}}</h5>
{{/each}}
Application outputs:
A Headline
Option 1
Option 2
Working demo - please notice that I'm using $.mockjax to recreate your response from server, but it matches format you provided.
Getting this error . Not sure why i am getting this error....would appreciate if someone can help me spot why this is erroring out.
Error while loading route: Error: Assertion Failed: You must include an id in a hash passed to push at new Error (native) at Error.Ember.Error
from the other posts related to similar error this has to do with a json where primary key is not handled correctly. But my json response looks correct.
****here are model objects:****
var PersonInfo = DS.Model.extend({
first: DS.attr('string'),
last : DS.attr('string'),
addresses: DS.hasMany('personAddress', {embedded: 'always'})
});
Ember.Inflector.inflector.irregular("personInfo", "peopleInfo");
export default PersonInfo;
var Address = DS.Model.extend({
type: DS.attr('string'),
personInfo: DS.belongsTo('personInfo')
});
export default Address;
****here is my deserializer:****
var PersonInfoSerializer = DS.ActiveModelSerializer.extend({
primaryKey: 'id',
extractArray: function(store, type, payload, id, requestType) {
var peopleInfo =payload.peopleInfo;
var adds = [];
// debugger;
peopleInfo.forEach(function(personInfo){
var addresses = personInfo.addresses,
addressIds = addresses.mapProperty('id');
adds.push(addresses);
personInfo.addresses = addressIds;
});
payload.addresses = adds;
return this._super(store, type, payload, id, requestType); }
});
export default PersonInfoSerializer;
****and here is the json response which i am mocking in API STUB****
server.get('/peopleInfo', function(req, res) {
var person_info = {
"peopleInfo": [{
"id": "1",
"first": "Tom",
"last": "Dale",
"addresses": [{
"id": "1",
"type": "Home"
}, {
"id": "2",
"type": "Work"
}]
}]
};
res.send(person_info);
});
I'm not sure why you were using the ActiveModelSerializer, but it doesn't really buy you anything if your data isn't coming down in the format that Rails generally provides.
You're data wasn't being formatted correctly. Additionally there is no need to write {embedded:'always'} that does nothing anymore. You'll probably want to look at the transition document https://github.com/emberjs/data/blob/master/TRANSITION.md .
App.PersonInfoSerializer = DS.RESTSerializer.extend({
extractArray: function(store, type, payload, id, requestType) {
var peopleInfo =payload.peopleInfo;
var adds = [];
peopleInfo.forEach(function(personInfo){
//debugger;
var addresses = personInfo.addresses,
addressIds = addresses.getEach('id');
adds = adds.concat(addresses);
personInfo.addresses = addressIds;
});
payload.personAddresses = adds;
return this._super(store, type, payload, id, requestType);
}
});
http://emberjs.jsbin.com/OxIDiVU/477/edit
Hello I am fairly new with ember and exploring it, I have been able to do a simple post to a resource, nevertheless it render my object like this
{"person":{"atribute1":"jjj","atribute2":"jjj"}}
Is there a way to remove the "login" like a custom serializer, my endpoint work by passing an object in the form of
{"atribute1":"jjj","atribute2":"jjj"}
Thanks.
The only solution I could find is override the createRecord, before I had
data[root] = this.serialize(record, { includeId: true });
I removed the index of root and got this instead:
App.Store = DS.Store.extend({
revision: 11,
adapter : 'App.CustomAdapter'
});
App.CustomAdapter = DS.RESTAdapter.extend({
createRecord: function(store, type, record) {
var root = this.rootForType(type);
var data = {};
data = this.serialize(record, { includeId: true });
this.ajax(this.buildURL(root), "POST", {
data: data,
context: this,
success: function(json) {
Ember.run(this, function(){
if ( this.rootForType(type) == 'login' ) {
return;
}
this.didCreateRecord(store, type, record, json);
});
},
error: function(xhr) {
//HERE to handle login operation failed
this.didError(store, type, record, xhr);
}
});
}
});
Maybe a attribute like withRoot or something similar might be required.