154

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?

Shawn Mclean
  • 56,733
  • 95
  • 279
  • 406
  • That's definitely weird. What you have looks like it should work just fine, based on [the API docs](http://documentcloud.github.com/backbone/#Collection-fetch). Are you using the latest version of Backbone.js? – Matt Ball Jul 12 '11 at 03:54
  • Can you try `JSON.stringify({ data: { page: 1} })`? – Joe Jul 12 '11 at 04:04
  • 1
    @Joe Tuskan, I'm not sure what to do with that, but I did: `collection.fetch(JSON.stringify({ data: { page: 1} }));` and nothing was passed in the url. – Shawn Mclean Jul 12 '11 at 04:08
  • Ok, do this: collection.fetch({ data:JSON.stringify({ page: 1}) }); – Joe Jul 12 '11 at 04:14
  • @Joe Tuskan, I got this: `http://localhost:1273/Items?{%22page%22:1}`, So I guess what I'm now looking for is converting json to url parameters. Else I'd have to just use a string. – Shawn Mclean Jul 12 '11 at 04:18
  • `{ data: $.param({ page: 1}) }` – Joe Jul 12 '11 at 04:20
  • Thanks, this works, could you make it into an answer so I can mark it? – Shawn Mclean Jul 12 '11 at 04:23
  • 3
    This works fine as you wrote it in Backbone 1.0 fyi – Dominic Jul 31 '13 at 12:51

4 Answers4

216

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.

Joe
  • 80,724
  • 18
  • 127
  • 145
71

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;
}
Jimchao
  • 1,468
  • 1
  • 12
  • 18
1

Another example if you are using Titanium Alloy:

 collection.fetch({ 
     data: {
             where : JSON.stringify({
                page: 1
             })
           } 
      });
peponline
  • 83
  • 8
-3
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);
}