Backbone.js fetch with parameters

Javascriptbackbone.js

Javascript Problem Overview


Following the documentation, I did:

var collection = new Backbone.Collection.extend({
        model: ItemModel,
        url: '/Items'
})

collection.fetch({ data: { page: 1} });

the url turned out to be: http://localhost:1273/Items?[object%20Object]

I was expecting something like http://localhost:1273/Items?page=1

So how do I pass params in the fetch method?

Javascript Solutions


Solution 1 - Javascript

changing:

collection.fetch({ data: { page: 1} });

to:

collection.fetch({ data: $.param({ page: 1}) });

So with out over doing it, this is called with your {data: {page:1}} object as options

Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default JSON-request options.
    var params = _.extend({
      type:         type,
      dataType:     'json',
      processData:  false
    }, options);

    // Ensure that we have a URL.
    if (!params.url) {
      params.url = getUrl(model) || urlError();
    }

    // Ensure that we have the appropriate request data.
    if (!params.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(model.toJSON());
    }

    // For older servers, emulate JSON by encoding the request into an HTML-form.
    if (Backbone.emulateJSON) {
      params.contentType = 'application/x-www-form-urlencoded';
      params.processData = true;
      params.data        = params.data ? {model : params.data} : {};
    }

    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
    // And an `X-HTTP-Method-Override` header.
    if (Backbone.emulateHTTP) {
      if (type === 'PUT' || type === 'DELETE') {
        if (Backbone.emulateJSON) params.data._method = type;
        params.type = 'POST';
        params.beforeSend = function(xhr) {
          xhr.setRequestHeader('X-HTTP-Method-Override', type);
        };
      }
    }

    // Make the request.
    return $.ajax(params);
};

So it sends the 'data' to jQuery.ajax which will do its best to append whatever params.data is to the URL.

Solution 2 - Javascript

You can also set processData to true:

collection.fetch({ 
    data: { page: 1 },
    processData: true
});

Jquery will auto process data object into param string,

but in Backbone.sync function, Backbone turn the processData off because Backbone will use other method to process data in POST,UPDATE...

in Backbone source:

if (params.type !== 'GET' && !Backbone.emulateJSON) {
    params.processData = false;
}

Solution 3 - Javascript

Another example if you are using Titanium Alloy:

 collection.fetch({ 
     data: {
             where : JSON.stringify({
                page: 1
             })
           } 
      });

Solution 4 - Javascript

try {
    // THIS for POST+JSON
    options.contentType = 'application/json';
    options.type = 'POST';
    options.data = JSON.stringify(options.data);

    // OR THIS for GET+URL-encoded
    //options.data = $.param(_.clone(options.data));

    console.log('.fetch options = ', options);
    collection.fetch(options);
} catch (excp) {
    alert(excp);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShawn McleanView Question on Stackoverflow
Solution 1 - JavascriptJoeView Answer on Stackoverflow
Solution 2 - JavascriptJimchaoView Answer on Stackoverflow
Solution 3 - JavascriptpeponlineView Answer on Stackoverflow
Solution 4 - JavascriptWalter von EntferndtView Answer on Stackoverflow