Ember-data: Empty payload with .save() - ember.js

Im stuck trying to.save() a record using Ember-Data 1.3 😵
When I perform a .save() nothing goes wrong but the request payload is empty:
I'm pretty convinced it's an issue with the ember-data request because from the back-end side the only data I got it's "token=blahblahblah". Also I took the request (copy as cURL) and I confirm it's empty:
Here's the .save() code:
var self = this;
this.set('isLoading',true);
return this.store.find('feed', feed_id).then(function(feed) {
//Setting the system_status of the feed to either 4 (archived) or 1 (normal)
feed.set('system_status',param);
//Persist to change to store (and server)
console.log(feed);
feed.save().then(function(){
//success
self.set('isLoading',false);
alert('ok');
},function(){
//Error
self.set('isLoading',false);
alert('error');
}) // => PUT to /feeds/id
});
RESTAdapter:
export default DS.RESTAdapter.extend({
host: 'http://localhost:8000/',
namespace: 'ed',
headers: {
"Content-type": "x-www-form-urlencoded" // workaround for laravel
}});
Model console.log before .save()
Any ideas?

The solution is indeed the Serializer, you can change it to send a POST request instead of a PUT request.
Update the DS.RESTAdapter with this code:
updateRecord: function(store, type, snapshot) {
var data = this.serialize(snapshot, { includeId: true });
var id = snapshot.id;
console.log(snapshot);
var url = ENV.apiUrl + "ed/" + snapshot.typeKey + "/" + snapshot.id;
return new Ember.RSVP.Promise(function(resolve, reject) {
jQuery.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: data
}).then(function(data) {
Ember.run(null, resolve, data);
}, function(jqXHR) {
jqXHR.then = null; // tame jQuery's ill mannered promises
Ember.run(null, reject, jqXHR);
});
});

Related

How to refresh a model after a request to API

//Route
url: "https://xxxxxx.com/api/entries",
users: "https://xxxxxx.com/api/users/",
model: function(){
var localData = JSON.parse(localStorage.getItem("user"));
var data = { auth_token: localData.user_token };
return new Ember.RSVP.hash({
logs: Ember.$.ajax({ url: this.get('url'), headers: { "X-Api-Token": data.auth_token } }),
team: Ember.$.ajax({ url: this.get('users'), headers: { "X-Api-Token": data.auth_token } })
});
}
//controller
actions:{
deleteWorklog: function( worklogId ){
var model = this.get('model.logs');
var data = { auth_token: this.get('local_data').user_token };
Ember.$.ajax({
method: "DELETE",
url: this.get('url') + "/" + worklogId,
headers: { 'X-Api-Token': data.auth_token }
}).then(function(data){
//how do i do it?
})
},
loadMore: function(){
var model = this.get('model.logs');
var url = this.get('url');
var today = new Date();
today.setDate(today.getDate() - this.get('from'));
console.log(today);
url += "?from="+ today.toISOString();
Ember.$.ajax({
url: url,
headers: { "X-Api-Token": data.auth_token }
}).then(function(data) {
model.replace(0, model.length, data);
});
var initial = this.get('from') + 10;
this.set('from', initial);
}
}
}
I'm blocked after the request, i need to refresh my model but i've to do cmd + R to see the change, is there a method re-call the model or something like that?
I've added another things maybe help
There's two ways that I can think of. The first is just to call the refresh method on the route. This is by far the simplest. Just call it and Ember will re-call the model hook for that route and any child routes. In your case, I would send an action from your controller to your route, then have your route refresh itself in that action handler.
The second way would be to manually re-get your data and set it on the controller. Perhaps something like this:
// route.js
actions: {
refreshModel: function() {
var route = this;
Ember.$.ajax({ ... }).then(function(data) {
route.get('controller').set('model', data);
});
}
}
However, I wouldn't recommend this method over the first. There are too many variables when dealing with Ember routing and it's easier just to let Ember handle it all.
You either want to use model.reload to refresh the record from the server:
http://emberjs.com/api/data/classes/DS.Model.html#method_reload
Or you may want to delete the record local:
http://emberjs.com/api/data/classes/DS.Model.html#method_deleteRecord
Or you may want to use model.destroyRecord to let Ember do the delete request (remote + local):
http://emberjs.com/api/data/classes/DS.Model.html#method_destroyRecord
I think it would be the best to use model.destroyRecord, but I assume there's a reason you do this manually?

How do I abort HTTP requests fired by Ember Data?

I have a model that have to be updated (reloaded) on certain user actions. If two of those actions happen in quick succession, I'd like the first update request to be aborted because a) it's result will be outdated, and b) the request takes some time (so queueing those requests is not an option either).
Is there a way to easily achieve this with Ember Data?
I overrode the application adapter's ajax method to add the XMLHttpRequest object to an array.
App.ApplicationAdapter = DS.RESTAdapter.extend({
xhr: [],
ajax: function(url, type, hash) {
var adapter = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
hash = adapter.ajaxOptions(url, type, hash);
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, adapter.ajaxError(jqXHR));
};
adapter.xhr.push(Ember.$.ajax(hash));
}, "DS: RestAdapter#ajax " + type + " to " + url);
},
});
Then, when I want to abort a request (in this case, from a route):
this.store.adapterFor('discussion').xhr.forEach(function(xhr) {xhr.abort();});

How to I specify a primary key for Ember Data?

My server uses sensorID as the primary key on my Sensor model. I've tried the following
App.SensorSerializer = DS.RESTSerializer.extend({
primaryKey: "sensorID"
});
based on what I see in this test, but it's not working. I'm getting an error:
Error while loading route: Error: No model was found for '0'
I'm using a custom adapter. The response is JSONP:
jQuery203041337518650107086_1397489458691([{"sensorID":1,"address":"XXX, YYY","latitude":"nnnn","longitude":"mmmm"...
but when I inspect the data that gets returned, it's a normal array:
// App.SensorAdapter
findAll: function(store, type, sinceToken) {
var url = 'http://blahblahblah/?callback=?';
var query = { since: sinceToken };
return new Ember.RSVP.Promise(function(resolve, reject) {
jQuery.getJSON(url, query).then(function(data) {
debugger;
// data.forEach(function(s) {
// s.id = +s.sensorID;
// });
Ember.run(null, resolve, data);
}, function(jqXHR) {
jqXHR.then = null; // tame jQuery's ill mannered promises
Ember.run(null, reject, jqXHR);
});
});
What is the correct syntax for Ember Data 1.0.0-beta.7?
Try this:
App.Adapter.map('App.Sensor', {
primaryKey: 'sensorID'
});

Delete All Record and Create new Records in Emberjs

In my Controller i have open action.this action should remove all record of model and then send ajax request and get new models and replace model. my ember data adapter is LSA
OlapApp.OpenController = Ember.Controller.extend({
needs: ['application'],
actions: {
open: function() {
var self = this;
var xhr = $.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'http://localhost:9095/service.asmx/getModel',
data: '{}',
success: function(response) {
//Success Empty AxisModel;
var data = JSON.parse(response.d);
self.store.findAll('axisModel').then(function(items) {
console.log('try to delete');
items.forEach(function(item) {
item.deleteRecord();
item.save();
});
});
setTimeout(function() {
//Fill Axis Model
_.each(data.axisModel, function(v, i) {
var record = self.store.createRecord('axisModel', {
id: v["id"],
uniqueName: v["uniqueName"],
name: v["name"],
hierarchyUniqueName: v.hierarchyUniqueName,
type: v["type"],
isMeasure: v.isMeasure,
orderId: v.orderId,
isActive: v.isActive,
isAll: v.isAll,
sort: v.sort
});
record.save();
});
self.get('controllers.application').send('showNotification', 'Open', 'success');
}, 2000);
}
});
}
}
});
but when i try to create a new models i get this error :
Assertion failed: The id a12 has already been used with another record of type OlapApp.AxisModel.
Assertion failed: The id a13 has already been used with another record of type OlapApp.AxisModel.
SOLUTION
finally i find the solution.for fix this problem just wrap deleteRecord() in Ember.run.once like this :
self.store.findAll('axisModel').then(function(items) {
items.forEach(function(item){
Ember.run.once(function(){
item.deleteRecord();
item.save();
});
});
});
For deleting records there are problems using forEach because the result of a find to the store is a live array. You can see this discussion in GitHub https://github.com/emberjs/data/issues/772. You can make use of toArray() in order to make a static copy of the live array)
self.store.findAll('axisModel').then(
function(items) {
items.toArray().forEach(function(item){
item.deleteRecord();
item.save();
});
});

ember-data customs serializing

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.