Replace a Backbone Collection with Server Data Using fetch({ reset: true })
Use fetch({ reset: true }) and a parse hook to replace a Backbone collection's contents with a full server response.
18 Sept 2026, 18:44 UTC

Problem: keep a client collection in sync with a full server list
Your Backbone application holds reference data on the client—for example, a list of countries, currencies, or status codes. The server publishes a new version of that list, and you want the client collection to match it exactly. Manually adding new models, removing stale ones, and skipping duplicates is error-prone. Backbone’s default fetch merges incoming models into the existing collection, which can leave outdated models behind or create duplicates.
Useful takeaway: call fetch({ reset: true }) on a Backbone.Collection so the server response replaces the collection contents in one request. Override parse to return an array of model attributes. This works best for read-only reference data that the server fully owns.
Prerequisites
- Backbone.js loaded in the page (this guide assumes the 1.x line, where
Backbone.syncdefaults to jQuery’sajax). - Underscore.js and jQuery available, because Backbone depends on Underscore and uses jQuery for AJAX by default.
- A server endpoint that returns JSON for the collection’s
url. - Access to edit the application source or run code in browser DevTools.
Procedure: define the collection and parse hook
parse runs on the server response before Backbone sets models on the collection. For reset to work, parse must return an array. Returning an object, undefined, or a non-array value can leave the collection empty or break the update.
const CountryCollection = Backbone.Collection.extend({
url: '/api/reference/countries',
model: Backbone.Model.extend({
idAttribute: 'code'
}),
parse(response) {
if (!response || !Array.isArray(response.results)) {
throw new Error('Expected response.results to be an array of country attributes');
}
return response.results;
}
});
const countries = new CountryCollection();
idAttribute tells Backbone which field uniquely identifies a model. When reset runs, Backbone can match incoming models to existing models by that id and preserve models that appear in both the old and new responses.
Procedure: fetch with reset and handle the response
Call fetch with reset: true. The request uses the collection’s url and, by default, an HTTP GET through Backbone.sync.
countries.fetch({
reset: true,
success(collection, response, options) {
// The collection now contains only models built from response.results.
// The 'reset' event has already fired.
},
error(collection, response, options) {
// Handle 4xx, 5xx, or network failures here. response.statusText may
// contain the HTTP status message for 4xx/5xx responses.
}
});
fetch returns a promise-like object, so you can also use .done() and .fail() instead of callbacks. Backbone does not retry automatically on network failure or HTTP errors; your application must handle offline states, 401 responses, and 5xx errors.
Listen to reset if you need to update the UI after the replacement:
countries.on('reset', () => {
console.log('Collection replaced. Model count:', countries.length);
});
Expected checks
| Check | How to verify |
|---|---|
| Request reaches the correct endpoint | Open browser DevTools Network, filter by XHR/fetch, and confirm a GET to /api/reference/countries returns 200 with JSON. |
| Collection length matches server | After success, confirm countries.length equals the number of items in response.results. |
| Stale models are removed | Run a second fetch({ reset: true }) with a shorter list, then confirm countries.get('old-code') returns undefined for a code removed from the response. |
| Error path works | Make the mock or staging server return 500 and confirm the error callback or .fail handler is invoked. |
Limitations and recovery options
- Unsaved changes can be lost.
resetremoves models that are not in the server response. If a removed model had unsaved local changes, those changes are discarded unless you save them first. parsemust return an array. Returning an object orundefinedbreaksresetand may leave the collection empty.- Large collections are expensive. A
resettriggers add/remove/reset listeners, so views bound to those events may re-render every model. - No automatic retry. Handle 401, 500, and offline failures in the
errorcallback. - jQuery dependency. If you remove jQuery,
Backbone.syncno longer defaults tojQuery.ajax, andfetchrequires a custom sync implementation.
Because reset changes collection state, there is no built-in undo. If you need a rollback path, keep a snapshot before fetching—for example, const snapshot = countries.toJSON();—and restore it manually if the server response is invalid. Otherwise, re-fetch the last known good payload.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.