Basic synchronization error even after response code 200

Welcome ninja backbone,

This is my first time using Backbone, so please excuse my noob. In my functionality (part of a larger application) I have a Backbone View vA supported by the mA model (as it should be), and the server side is in Spring MVC with annotated Spring management methods with @RequestBody and @ResponseBody. Jackson works fine for me with Spring.

Now in the application

Backbone.Model |_ BaseModel (custom base model for our app) |_ mA (my model) 

mA has its own endpoint, and this trunk successfully calls this when creating a PUT request, that is, when I call save () from the send button's event handler from View vA, for example:

this.model.save ({

  success : function(){ alert('Request submitted successfully'); }, error : function(){ alert('Something awful happened.'); } 

});

Our BaseModel has the following:

 define([], function() { window.BaseModel = Backbone.Model.extend({ ...... }); onSyncError : function(model, response) { switch (response.status) { case 403: [...//some more code ] default: alert(bundle.getDefault('HTTP_RESP_OTH') + response.status); } }, onSyncSuccess : function(model, response) { alert('Sync done! '); }, sync : function(method, model, options) { options.error = this.onSyncError; Backbone.sync.call(this, method, model, options); ....//some more stuff. }, } 

Spring controller method:

 @RequestMapping(value="/resource/xyz/{id}.json", method = RequestMethod.PUT, consumes = {"application/json"} , produces = {"application/json"}) @ResponseBody public Map<String,String> methodX(@RequestBody XyzDTO xyzDTO){ .... map.put("msg", "success"); return map; } 

In addition, before making a save call, I change several attributes of the model, since the server-side DTO has a different structure:

 this.model.unset("abc",{ silent: true }); this.model.set( { abc: {id : "2",xyz:{ ... //more code } ); 

The problem is that the save () call generates a PUT request and successfully calls the Spring endpoint handler, but I get a 200 response code (which I expect), but when I spend the call with Firebug it goes to the onSyncError method and gives me a message about an error (due to the "default" case in it).

The Backbone doc document says: "When returning a JSON response, send the model attributes that have been changed by the server and need to be updated on the client." Well, I don’t need to update the model on the client side, its one of the last screens, and I just need to inform the user about the success / error and redirect it to the main page / control panel.

I read a little more, and it seems that the 200 code as an answer is not enough - there may be JSON analysis errors that lead to synchronization failure.

I checked the answer in Firebug and the JSON response looks like {"msg": "Success"}.

So what could be wrong?

+8
javascript spring spring-mvc
source share
3 answers

Thank you for your time. I finally was able to get around the problem by using $ .ajax to execute the PUT request, thereby bypassing all the Backbone synchronization. My ajax callback success handler processes the response, and there are no more synchronization errors (since it was not called anyway) :)

+1
source share

Backbone.Model.save() expects the response from the server to be an updated hash of the model values. If your answer is {"msg":"Success"} , the Backbone may not sync with your model. Basically, it interprets your HTTP 200 JSON response as model attributes and tries to synchronize the model accordingly.

You can try: 1) Set the path to the Spring controller to return a JSON-ified model response, 2) return a simple 200 with an empty response body, or 3) write a custom parse that looks for answers with the format {"msg":"Success"} and responds differently.

+9
source share

I will share my experience with the same problem; the user base model and the caller model.save and no event events.

My problem was using the custom set feature in the base model, which did not return "this".

If you look into the basic source code to save the model, you will find this snippet:

  options.success = function(resp) { // Ensure attributes are restored during synchronous saves. model.attributes = attributes; var serverAttrs = model.parse(resp, options); if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { return false; } if (success) success(model, resp, options); model.trigger('sync', model, resp, options); }; 

In my case, the model.set command (serverAttrs, options) could not be executed, and the save function returned false before any events were triggered.

This may not be your problem, but hopefully it helps someone else ...

0
source share

All Articles