I use backbone model to save the data to the server. then I handle the success or error callback after save(post) and set wait:true. my question is why backbone model only trigger the error callback when server returns a string? when server returns a json or any number, it will go to the success. the problem is if I want to return a multiple error message and I want to put all error message into a collection(json), it will never go to error callback. sample code like
echo 'success'; //actually it will go to error callback cuz it return a string(any string)
echo json_encode($some_array); // it will go to success
echo 200/anynumber; // it will go to sucess
My solution is if I wanna return a multiple message, I can separate those message by a delimiter, and use javascript native function split to separate them. is there any better solution like maybe I can return a state(indicate either success or error) and a collection from server?
model code looks like:
somemodel.save({somedata},
{
success:function(a,b,c){},
error:function(b,c,d){},
wait: true
});
Backbone expects JSON as the default response format. When you get an integer, i suspect, backbone is using jquery $.parseJSON()
on the number and returns it as valid JSON while it is not. If you want to return multiple errors messages, i suggest you put them into separate fields of an array and encode them then send as response to backbone.
Just checked backbone source code and it doesn't call on $.parseJOSN()
contrary to what was guessed above.
Assume you have the following PHP code (as much as I would like to create a framework agnostic example, it is possible but things will be quicker and smoother using a framework so I have picked Slim).
When you save a model, backbone sends the data to the server using POST as the method. In Slim this will translate into the following:
$app = new \Slim\Slim();
$app->post('/authors/', function() use($app) {
// We get the request data from backbone in $request
$request = $app->request()->getBody();
// We decode them into a PHP object
$requestData = json_decode($request);
// We put the response object in $response : this will allow us to set the response data like header values, etc
$response = $app->response();
// You do all the awesome stuff here and get an array containing data in $data //
// Sample $data in case of success
$data = array(
'code' => 200,
'status' => 'OK',
'data' => array('id'=>1, 'name' => 'John Doe')
);
// sample $data in case of error
$data = array(
'code' => 500,
'status' => 'Internal Server Error',
'message' => 'We were unable to reach the data server, please try again later'
);
// Then you set the content type
$app->contentType('application/json');
// Don't forget to add the HTTP code, Backbone.js will call "success" only if it has 2xx HTTP code
$app->response()->status( $data['code']);
// And finally send the data
$response->write($data);
I have used Slim simply because it gets the job done and everything should read like English.
As you can see, Backbone will need the response in JSON format. I just tested on one of my websites, if you send an HTTP code different from 2xx, Backbone will actually call error
instead of success
. But the browser will also catch that HTTP code, so watch out!
REMOVED INFO
Backbone parse
function will be expecting JSON as well! Assume we have this collection:
var AuthorsCollection = Backbone.Collection.extend({
initialize: function( models, options ) {
this.batch = options.batch
},
url: function() {
return '/authors/' + this.batch;
},
// Parse here allows us to play with the response as long as "response" is a JSON object. Otherwise, Backbone will automatically call the "error" function on whatever, say view, is using this collection.
parse: function( response ) {
return response.data;
}
});
parse
allows you to inspect the response, but will not accept anything else than JSON!