sencha touch 2 store proxy api reading response - extjs

I have a store with a proxy configured to update my database.
proxy: {
type: "ajax",
api: {
create: MySite.app.BaseURL + 'Member.php?action=create',
read: MySite.app.BaseURL + 'Member.php',
update: MySite.app.BaseURL + 'Member.php?action=update',
destroy: MySite.app.BaseURL + 'Member.php?action=delete'
},
This all works fine but what I would really like is to be able to read the response so to report to the user success or failure of an update.
For example when an update is successful the json below is returned in the response,
{"success":true,"message":"Updated"}
And if not successful then the following is returned,
{"success":false,"message":"something terrible happened"}
I've tried adding a listener to the store as below but this doesn't seem to pick up the response.
listeners: {
success: function(response) {
console.log(response);
var data = Ext.JSON.decode(response.responseText.trim());
console.log(data);
if(data.success == 'true') {
console.log('success');
}
}
},
Could anyone help?

Stores don't fire a success event. That has to be configure in each operation using the success, failure or callback functions.
For example, when you perform a sync, you could do something like this:
myStore.sync({
success: function(batch, options) {
console.log(response);
}
});
Given stores work with bacths, to have to see the batch fields in order to know if it was okay or not.

The store will fire a 'write' event when successful. The proxy will fire an 'exception' event if there is a failure. This 'exception' event should bubble up to its parent (the store) so your listeners in the store should be for 'write' and 'exception'. You can look up the parameters to these events. For the 'write' event, the parameters should be the store itself, and the operation. The operation should have all the info you need to do the logging or whatever you want.

Related

Handling Ajax response with success and without failure

The below code has both success and failure handling
jQuery.ajax({
type:"post",
dataType:"json",
url: myAjax.ajaxurl,
data: {action: 'submit_data', info: info},
success: function(data) {
successmessage = 'Data was succesfully captured';
$("label#successmessage").text(successmessage);
},
error: function(data) {
successmessage = 'Error';
$("label#successmessage").text(successmessage);
},
});
$(":input").val('');
return false;
However we are not following the above...We are following as below
jQuery.ajax({
type:"post",
dataType:"json",
url: myAjax.ajaxurl,
data: {action: 'submit_data', info: info},
success: function(data) {
if(data.responseType == 'success') {
// success
}
if(data.responseType == 'failure') {
// failure
}
}
});
$(":input").val('');
return false;
Is our approach is the correct or wrong approach ??
Basically every response will be success and show error message based on the response type
Please advise. We need to follow the best practice
data. responseType doesn't return a 'success' or 'failure'. It is contains an enumerated value which represents the type of response coming back to you like text, json, arrayBuffer etc..
Hence in the second code block both if statements will be exceuted to be false and nothing will be done with the response received.
I think you should go with the first approach because
Whether you are using raw JS or a library to implement this functionality, you'll have access to the state of the request i.e. whether the request was successful; met with an error and finally whether it has been completed.
Make proper use of these events and their respective callbacks to manipulate the UI for a better user experience. For example, if the request was unsuccessful, you'd want to update the user interface to reflect that their changes weren't successful while if it was successful, you'd want to tell them so. Don't keep the user waiting!
With jQuery, you'd make use of the success and error callbacks. You also get other callbacks such as complete and beforeSend to be invoked for apporopriate use.
$.ajax({
//Other code
success: function(msg)
{
// Update the UI here to reflect that the request was successful.
doSomethingClever();
},
error: function(msg)
{
// Update the UI here to reflect that the request was unsuccessful
doSomethingMoreClever();
},
complete: function(msg)
{
// Update the UI here to reflect completion
doSomethingEvenMoreClever();
}
});
take a look at this

AngularJS ngResource delete event not calling callback

I have this code:
dogsResource.delete({id: $stateParams.dogId}, angular.noop,
function(value, responseHeaders){
//Success
console.log(value);
console.log(responseHeaders);
},
function(httpResponse){
//Error
console.log(httpResponse);
}
);
The delete is done, the problem is that neither success nor error is being called. I've also tried using an instance (that means, to use $delete), but it didnt work either.
I tried testing the callbacks with other methods, such as get
$scope.dog = dogsResource.get({id: $stateParams.dogId}, function(value, res){
console.log(value);
});
And it works. I don't know why that happen, since the dog is being deleted from database.
Thanks
UPDATE
dogResource code
// Return the dogs resource
.factory('dogsResource', ['$resource', function($resource){
return $resource("http://localhost:5000/dogs/:id",{id: "#id"},{update: {method: "PUT"}});
}])
UPDATE 2
I Found the error. It was in the RESTful API (Node js). The method was not sending anything to Angular, so no callback was triggered:
//DELETE - Delete a dog with specified ID
exports.deleteDog = function(req, res) {
console.log('DELETE' + req.params.id);
Dog.findById(req.params.id, function(err, dog) {
dog.remove(function(err) {
if(err) return res.status(500).send(err.message);
console.log('Succesfully deleted.');
res.status(200);
})
});
};
Replacing res.status(200) with res.status(200).end() got the callback triggered.
Thanks you all for your time.
I suggest to you to not use
res.status(200).end()
In fact usually when you delete an object with a REST service in expressJS, the common case is to send the deleted object as response, because it could be useful for the frontend to get this object (and to make sure that it's the good object).
So instead of use
res.status(200).end()
use
res.send(dog)
Or if you want to send an empty response, the status code for a delete operation should be :
res.status(204).end()
204 NO CONTENT
Note that you don't need to set the status code by default it will be 200. So set status code to 200 is just useless.
And to finish an http response needs to be sent to close the request. The end method or the send method make that. Set a status code to a response http will never send anything to the frontend. That's why your angular callback was never fired.
So i suggest to you to add the tag expressjs to your question, because it's not an AngularJS problem but a real expressJS mistake.
In your code, the second argument is angular.noop:
dogsResource.delete({id: $stateParams.dogId}, angular.noop,
function(value, responseHeaders){
//Success
console.log(value);
console.log(responseHeaders);
},
function(httpResponse){
//Error
console.log(httpResponse);
}
);
According to the ngResource Source Code, if you set the second argument to a function (angular.noop is a function) then it will use the second argument as the success callback. Since the second argument is a no-operation, nothing will happen when it is called.
Try setting the second argument to function (r) { console.log (r) } and see what you get.
I'm recently working with ngResource. In my case, I've have used three parameters in that api call. Therefore, you could use
dogsResource.delete({id: $stateParams.dogId}, function(value, responseHeaders){
//Success
console.log(value);
console.log(responseHeaders);
},
function(httpResponse){
//Error
console.log(httpResponse);
}
);
I hope that helps.
Use promise return by the $resource object. As $resource object by default return a promise object, and that promise object is available .$promise variable over that $resource API method.
Code
dogsResource.delete({id: $stateParams.dogId}).$promise.then(function(data)//Success
console.log(value);
},
function(httpResponse){ //Error
console.log(httpResponse);
});

Handling errors using angular $q.all

I have an angular app that displays an editable grid to the user. The user is allowed to edit multiple rows in the grid, then save all those changes at once. When they do this, I am using $q.all to send out all the update calls to an API in parallel.
I want to be able to display an error to the user for each call that fails with some of the information about the object that wasn't saved correctly, but I can't figure out how to get that information out of the error handler.
var ops = []
_.each($scope.items, function (item) {
if(item.Modified)
ops.push(dataService.update(item.itemID, item.otherField))
})
$q.all(ops)
.then(function (repsonse) {
//success
},
function (response) {
//in here I want to output the itemID and otherField values for the item(s) that failed
})
Each item that is being sent out on the API call has a few properties on it (itemID and otherField). I want those values to be include in the error message to the user.
Is this possible using q.all or do I have to use another method?
$q.all will trigger the error callback if any of the operations fail at any time, but in your case you just want to record which ones (if any) failed without triggering any additional error. I would use return a promise from .catch:
ops.push(dataService.update(item.itemID, item.otherField))
.catch(function () {
return {
status: "failed",
id: item.itemID
};
});
Then in $q.all's callback you can iterate over the responses and check for .status == "failed" and check those IDs.

Backbone.js Work with server response to save() method

I'm kind of new to Backbone. I need use the data in the server response to a save() method but I'm not sure how to get it. This is the code:
$(".act_btn").on("click", function(){
var act_id = $(this).attr("data-id");
startRecordItem = new StartRecordItem({
activity: act_id,
});
startRecordItem.save({
success: function(response){console.log(response)}
});
/*
recordItem = new RecordItem({
id: ... <---- I have to populate this with the data from the server response.
});
*/
Right now the success function doesn't work at all, what am I missing? I'd like to get an attribute from the JSON response and then use it on the ´new RecordItem´. The save itself works correctly and the response looks like this:
{"activity": 1, "id": 14}
What you're missing is that the first argument of .save. is the attributes that get passed into the model, pre-save. You want to do something more like this:
startRecordItem.save(null, {
success: function(response) {
console.log(response);
}
});
Since Backbone fires a sync event on successful save, you could also do this:
this.listenTo(startRecordItem, 'sync', function() { /* logic here */ });

Updating scope on form submit

I have a form that upon submit will POST a message to our REST API.
If successful, the REST API will return the updated value in the same JSON format as the GET call makes.
For some reason, even after the POST call has finished, the {{escalation.policy}} is still not updated in the scope.
var escalation = Escalation.save({
policy: $scope.policy,
}).$promise.then(function (data) {
$scope.escalation.push(data);
alert(data);
},
Is your REST request coming in then function? Try to put error function next to then() and make sure your request is successfully executed and responded back.
You need to call $scope.$apply() after $scope.escalation.push(data);. That will cause a new $digest to occur forcing the view to update, my guess is that $promise.then is ocurring outside the usual digest loop.
This is the current full segment of code for the submit()
$scope.submit = function () {
var Escalation = $resource('/api/escalation');
var escalation = Escalation.save({
policy: $scope.policy,
}).$promise.then(function (data) {
$scope.escalation.push(data);
}, function (error) {
alert('This request could not be processed. Please try again later.');
console.log(error);
});
};
The API will always return in the following format for a GET or POST:
{"policy":"Whatever the current/new policy is."}
Alas, i can still not seam to figure out why the view will not update.

Resources