I've got a User model that gets POSTed to the server to create a user on the system. The response is basically:
{
success: false,
message: "User already exists"
}
Cool, within my model I have a REST Proxy. The proxy has a JSONReader attached to it as well with the following:
messageProperty: 'message',
successProperty: 'success'
so I create my user and save it with something like:
var user = Ext.create('App.model.User', {name: "Bill"});
user.save(function (records, operation) {
console.log(records);
console.log(operation);
});
But I can't see anywhere to grab the error message that was returned from the server. All I can grab is: isSuccessful() which seems to correctly say false.
There doesn't seem to be ANYTHING in the documentation about this. I can't understand why something like this isn't included or how I'm missing it.
operation.getResponse(); returns null as well. I've also tried passing in a config with success, failure and callback... seems to be nothing there for me
Thanks, Dom
Try operation.getResultSet().getMessage(). I haven't tried it, but looking at the source code, it seems like this should work.
Looks like you can pass in a object with a success and fail methods. From the docs http://docs.sencha.com/touch/2-0/#!/api/Ext.data.Model-method-save
options : Object/Function
Options to pass to the proxy. Config object for Ext.data.Operation. If you pass a function, this will automatically become the callback method. For convenience the config object may also contain success and failure methods in addition to callback - they will all be invoked with the Model and Operation as arguments.
So you should be able to do:
var user = Ext.create('App.model.User', {name: "Bill"});
user.save({
success: function(){
},
failure: function(){
}
});
I don't know what is the callbacks, but usually what I do to find out:
success:function(a,b,c,d){
console.log(a,b,c,d);
}
and then look at the data in my console and rename the vars accordingly.
Hope this helps.
var user = Ext.create('App.model.User', {name: "Bill"});
user.save({
success : function(){
console.log('success', arguments);
},
failure : function(model, operation){
var reader = model.getProxy().getReader(),
message = reader.getMessage(reader.rawData)
console.log('failure message : ' + message);
}
});
Related
This is somewhat related to other similar questions:
jquery ajax returns error but is success
jquery .ajax always returns error - data being added to database
Jquery Ajax Call always returns error
However, my problem doesn't seem to be the data:"json" issue.
My code is a simple POST request to a server and, for testing purposes, it is always returning 200 OK.
If I run the jquery code directly after document ready, it works just fine and calls the success function.
But if I attach it to a on("click") button event, it always return the error function. Nothing has changed on the server and I can see on the console that the right resource is being called.
My main code is located on a js file:
var myObj = function(){
var url = "myURL";
this.functionINeed = function(data, cb) {
ajaxPost(url, data, cb);
};
function ajaxPost(url, data, cb){
$.ajax({
"url" : url,
"contentType" : "application/json; charset=UTF-8",
"data" : data,
"type" : "POST",
"success" : function(serverData, textStatus, jqXHR){
cb(null, {
"serverData" : serverData,
"textStatus" : textStatus,
"jqXHR" : jqXHR
});
},
"error": function (jqXHR, textStatus, errorThrown) {
cb({
"jqXHR" : jqXHR,
"textStatus" : textStatus,
"errorThrown" : errorThrown
});
}
});
};
}
//I initialize the object directly on the js file
MyObj = new myObj();
Then, the first scenario: call the function directly on page load:
var data = {
"action" : "someaction",
"code" : "somecode"
}
MyObj.functionINeed(JSON.stringify(data), function(err, response){
if(err){
alert(err.errorThrown);
return err;
}else{
alert(response.textStatus);
return response;
}
});
This works fine: the server is called, the content is returned and JQuery calls the success function.
However, if I attach this code to a button event, it always returns the error function. I am monitoring the server and I am sure it is returning the correct data.
$("#myButton").on("click", function(){
var data = {
"action" : "someaction",
"code" : "somecode"
}
MyObj.functionINeed(JSON.stringify(data), function(err, response){
if(err){
alert(err.errorThrown);
return err;
}else{
alert(response.textStatus);
return response;
}
});
});
For the records, my server is Node.js with Sails.js, but this doesn't seem to matter.
The many similar questions are somehow related to the data:"json" issue, but I've removed it and the most weird is that the behavior only happens when you attach the code to an event.
I would suspect there is some kind of scoping issue involved (object being instantiated on the file, for ex.), but the server is being correctly called every time. I just can't understand why JQuery interprets all responses as errors (and empty server data).
What am I doing wrong here?
After an insane afternoon trying all kinds of combinations, a light bulb went off and I figured out the problem is that my button html was inside a form.
<form>
<button></button>
</form>
After changing to a regular div, it worked.
<div>
<button></button>
</div>
Which is -- to me -- absolutely insane. It seems JQuery captures more information than meets the eye when sending the ajax query, and this was messing the response parsing by expecting some form encoded behavior. Does it mean I cannot have special purpose buttons inside my forms? Since I am using Bootstrap, that's "OK" because I can use the a tags for this (tested and worked). But this seems a JQuery bug (version: 1.11.2)
I have a collection that fetches with this line:
console.info("before fetching drivesCollection");
this.drivesCollection.fetch({
success: function() {
console.info("inside fetching drivesCollection");
},
error: function(collection, response, options) {
console.log('ERROR fetching drivesCollection ');
}
});
console.info("after fetching drivesCollection");
the fetching works as expected, and the error callback never get's called. I can see all models (200+) inside the collection afterwards. The problem is that anything inside the success function is not being called. I need to put a function there.
I tried to debug why the success function is being skipped somehow using the parse function of the collection definition as this:
parse: function(response){
console.log('starting parsing of drivesCollection');
console.log(response.length);
console.log(response);
return response
},
it works as expected, and returns valid values that are inserted into the collection...
Any ideas why my success function never runs?
Two things I think of is:
1) Your server isn't sending the right header information concerning content type in which the quick fix would be to force the use of getting JSON data by adding the parameter
this.drivesCollection.fetch({
dataType: 'json',
success: function() {
console.info("inside fetching drivesCollection");
}
});
2) OR, you're mistakenly are using a Backbone.Model to fetch collections and not a Backbone.Collection (I've made that mistake a few times)
I've created a custom object, called 'Opinion' to build custom stories around it.
I'm trying to add some app-owned objects from my website using the javascript sdk.
The sample code facebook gives me is:
FB.api(
'me/objects/[namespace]:opinion',
'post',
{
app_id: xxxxxxxx,
type: "[namespace]:opinion",
url: "http://samples.ogp.me/331257847005141",
title: "Sample Opinion",
image: "https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png",
description: ""
},
function(response) {
// handle the response
}
);
The reponse is an error (OAuth Exception):
2500: Cannot specify type in both the path and query parameter.
If i remove the type parameter, i get another error:
(#100) The parameter object is required
Same if I remove [namespace]:opinion from the path.
I don't understand why, and there's no reference about this after googling it.
Why this? Any resource i can refer to solve that?
The object is a JSON-encoded version of an object, the sample code generated for you was incorrect. Also remove type from the parameter list.
So something like,
FB.api(
'me/objects/[namespace]:opinion',
'post',
{
object: {"app_id":xxx,"url":"http:\/\/samples.ogp.me\/331257847005141","title":"\"Sample Opinion\"","image":"https:\/\/s-static.ak.fbcdn.net\/images\/devsite\/attachment_blank.png","description":"\"\""}
},
function(response) {
// handle the response
}
);
An example of how it looks can be seen at http://philippeharewood.com/facebook/objectify.html and it was based off the curl example given at https://developers.facebook.com/docs/opengraph/using-object-api/
For anyone struggling with a similar problem on iOS, the sample code again appears to be wrong, however the following seems to work:
NSMutableDictionary<FBOpenGraphObject> *object =
[FBGraphObject openGraphObjectForPostWithType:#"<appnamespace>:<objecttype>"
title:#"..."
image:[result objectForKey:#"uri"]
url:nil
description:#"..."];
[FBRequestConnection startForPostOpenGraphObject:object completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
// handle the result
if ( error ) {
DLog(#"error %# creating object", error);
} else {
...
}
}];
I have a HTML-page with some JS-code in it, which is loaded from the Android WebView. This JavaScript uses the jQuery-post-function to call the HandleAndroidJSON.aspx-site with data, and return a callback-function with a data-, status- (and jqXhr-) parameter:
function syncWithServer() {
var dataToSend = Android.getDataToSend();
$.post("HandleAndroidJSON.aspx", { data: dataToSend }, callbackDataFromServer);
}
function callbackDataFromServer(data, status) {
Android.setDataFromServer(data, status);
}
The "Android"-variable is a JavaScriptInterfacecreated in Android that makes it possible to call Android-methods from JS.
In my HandleAndroidJSON.aspx.cs-file I write a response depending on the data I receive from Android:
public partial class HandleAndroidJSON : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = "text/plain";
// Read request parameter and deserialize JSON data.
string jsonDataFromClient = Request.Params["data"];
// ... Do stuff with the data ...
if (error != null)
{
//This goes into the data-parameter of the callbackFunction
Response.Write(error);
//Response.Status = "403 Error"; //This seems to only be HTTP-status responses,
//not the one used as parameter in the callback-function
}
else
{
//This does too
Response.Write(jsonDataToSend);
}
Response.End();
}
}
The Response.Write()-method returns in the the data-parameter in the callback-function as intended, but I cannot seem to set the status-parameter - it always returns the same string: "success" and doesn't change if I set the Response.Status-property.
So the question is simply, how do I set the status-parameter of the callbackDataFromServer-function (that is called from the jQuery-post-function) from the aspx.cs-code?
EDIT: I'm not talking about status-codes for HTTP. Setting the StatusDescription-, StatusCode- and the Status- properties, of the Response-property, doesn't change the status-parameter of the callback-function.
EDIT2: I don't think handling the status-parameter in the JavaScript-code solves the problem because I would have to validate the data in Android again anyway (since JavaScript-injection would be possible to do to avoid the error handling). I would like to pass it on to the Android-method via the status-parameter, in the callbackDataFromServer-function, as the current code indicates.
EDIT3: Even though I can't seem to find a straight answer to whether it's possible to set the status-parameter from the aspx-code, it seems that the only thing you can change beside the data-parameter is the jqXhr.status property, which can be set be the Response.StatusCode property in the aspx-site.
There's also the jqXhr.statusText property which holds a string, but it seems to be the default text, based on the statuscode, and not the Response.StatusDescription (setting the statusCode to 200 and the statusDescription to "success" returned as "OK", which is default for the statusCode 200).
This is the topic I was reading: Get the jqXhr.responseText on a jQuery getJSON request using JSONP
EDIT4: I now figured out that setting the StatusCode to a value, that implies something went wrong, will result in no data being sent, even though the Response.Write()-method has been called, which defeats the purpose I'm trying to achieve.
The proper question would then be: How can I properly pass on the error text (from ASP.NET, through jQuery) if something went wrong, instead of the data? And how can I ensure that the data I'm transfering is either an error or JSONData?
I figure the simple way is just to check if the data starts with a "{" or "[" but I feel like it's a bit of a hack.
inorder to get the status code you can use the status property of the third argument of success call back jqXHR, here is the fiddle http://jsfiddle.net/prD5c/
so your function looks like
function callbackDataFromServer(data, status,jqXhr) {
console.log(jqXhr.status);
Android.setDataFromServer(data, status);
}
you can use the statusCode like
$.ajax({
statusCode: {
202: function() {
alert("success");
},
403:function(){
alert(error);
}
}
});
as you are using $.post you can define this in the ajaxSetup like
$.ajaxSetup({
statusCode: {
202: function() {
alert("success");
},
403:function(){
alert(error);
}
}
});
http://api.jquery.com/jQuery.ajax/
I am using the following code to save additional properties to a model (answer model in this case)
selectMedia: =>
# Post media to server
#options.answer.id = #options.answer.get('_id')
#options.answer.url = "/v1/answers/#{#options.answer.get('_id')}"
#options.answer.save
youtube_id: #options.media.get('vid')
success: (result) =>
$('.modal').html('')
$('.modal').modal('toggle')
#options.question_view.remove()
#options.question_view.render()
error: ->
console.log("error")
I want to execute a set of commands only when the save is executed successfully.
I tried the code above but it is not working (although I checked that the data was indeed saved)
Please advise on how I can modify the code to check for the success event
You're using save incorrectly. Backbone's save takes separate attributes and options arguments:
save model.save([attributes], [options])
[...]
save accepts success and error callbacks in the options hash,
but you're only passing one hash. You need to call it like this:
#options.answer.save { youtube_id: #options.media.get('vid') }
success: (result) =>
$('.modal').html('')
$('.modal').modal('toggle')
#options.question_view.remove()
#options.question_view.render()
error: ->
console.log("error")
or perhaps like this if you really hate braces:
#options.answer.save 'youtube_id', #options.media.get('vid')
success: (result) =>
$('.modal').html('')
$('.modal').modal('toggle')
#options.question_view.remove()
#options.question_view.render()
error: ->
console.log("error")