11

I've been looking through multiple posts about how to save a Backbone collection using a non-RESTful server and I'm still a little confused. I've created a collection where I've overridden the toJSON method to customise my data for posting to my API ("/api/entity/735/request/personDelete" currently swapped out for jsfiddles /echo/json). So I've created a save method which uses Backbone.sync, on success I'm logging out any kind of response and the object is empty, not sure where things get lost or what I'm doing wrong; can anyone give me some guidance? Would just like to get this example working so I can use something like this going forward.

JS

var PersonCollection = Backbone.Collection.extend({
    model: PersonModel,

    url: function() {
        // Dummy JSFiddle endpoint
        // Example non-RESTful url "/api/entity/735/request/personDelete"
        return '/echo/json/';
    },

    /**
     *  Override toJSON to loop through collection models making
     *  custom objects containing specific attributes to be posted.
     */
    toJSON: function() {
        console.log(this.models);

        var plucked = this.models.map(function(model) {
            return _.pick( model.toJSON(), ["id","name", "teams"] )
        });

        console.log(plucked);
        return plucked;
    },

    save: function(options) {
      Backbone.sync('create', this, {
        success: function(data, textStatus, jqXHR) {
          console.log('Saved!', data);
        }
      });
    }
});

JSFiddle: http://jsfiddle.net/kyllle/f1h4cz7f/3/

styler
  • 15,779
  • 23
  • 81
  • 135
  • Plase check if the request is made, the parameters are passed as expected (which I doubt) and you get an 2xx response. Please edit your post an specify how a request should look like (e.g. form-encoded or application/json etc.). I'd say that event `Backbone.sync()` might not be suited for your needs. You'd probably want to use `$.ajax()` directly in `save()` or, if you have more models and collection which communicate with that "non-standard" REST API you may want to overwrite `Backbone.sync()` instead. – try-catch-finally Oct 14 '15 at 21:29
  • That's kinda part of my problem right now, I'm not sure where or how I need to pass the parameters so save can be run effectively? – styler Oct 14 '15 at 21:52
  • 1
    Are you really meant to be saving everything inside the collection? I know you said that your backend is not RESTful, but what is it that your backend is expecting? and how is it expecting json? – Javier Buzzi Oct 20 '15 at 23:01
  • styler, note: you haven't responded to Javier's and mine requests for details (even though you're not sure what and how to do you should be at least feel certain what your requirements are). Does Yura's answer answer your question / is helpful? – try-catch-finally Oct 24 '15 at 23:00
  • sorry it has taken me a while to respond, i think my problem is right now that I don't see the updated data that I've amended in toJSON in my save response. I click post data and then I see toJSON has made the correct updates only using id name and teams and then save fires but the success only shows a blank object, just wondering how these get connected correctly? – styler Oct 25 '15 at 11:17

2 Answers2

7

You don't have to force yourself to use sync if it doesn't help you. sync is there to save you time in common scenarios.

As you can see in the annotated sync code, it eventually just calls jQuery.ajax and includes logic to help with RESTful backends.

Also it triggers some events, which you might or might not listen in other parts of your app, like request (when the request was made) and sync (when the request was successfully completed), or error (if the request failed)

All of these you can do from your app, if reinventing sync isn't exciting.

Prepare your data, call $.ajax to send the data to your backend, and optionally trigger the backbone events, if you're going to listen to them.

Yura
  • 2,690
  • 26
  • 32
  • Yeah I totally understand where you are coming from with this but I thought I could combine toJSON and sync to do this in a nicer way – styler Oct 25 '15 at 11:18
0

You can wrap your collection inside a backbone model.

var CollectionWrapper = Backbone.Model.extend({
    url: "/echo/json"
});

and then you can use model.save() and/or Backbone.sync() as Backbone intends it to be used.

See this answer : "How" to save an entire collection in Backbone.js - Backbone.sync or jQuery.ajax?

Community
  • 1
  • 1
anurag_29
  • 922
  • 10
  • 19
  • This is rather a comment. Apart from this, the OP asks how to deal with (REST) APIs that do not follow Backbone's principle. He says `"a non-RESTful server"` and `"/api/entity/735/request/personDelete"` looks more like the verb (action) is reflected by URL components, not by HTTP-verbs. I guess the OP already realized s/he has to override `save()` or `sync()` but isn't sure how to do that. – try-catch-finally Oct 25 '15 at 09:33