Created
June 26, 2014 20:06
-
-
Save remixz/46b07c961f0cc3e10ad7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var _ = require('underscore'); | |
var xhr = require('xhr'); | |
var qs = require('qs'); | |
// Throw an error when a URL is needed, and none is supplied. | |
var urlError = function () { | |
throw new Error('A "url" property or function must be specified'); | |
}; | |
module.exports = function (method, model, options) { | |
var type = methodMap[method]; | |
var headers = {}; | |
// Default options, unless specified. | |
_.defaults(options || (options = {}), { | |
emulateHTTP: false, | |
emulateJSON: false | |
}); | |
// Default request options. | |
var params = {type: type, responseType: 'json'}; | |
// Ensure that we have a URL. | |
if (!options.url) { | |
params.url = _.result(model, 'url') || urlError(); | |
} | |
// Ensure that we have the appropriate request data. | |
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { | |
params.json = options.attrs || model.toJSON(options); | |
} | |
// For older servers, emulate JSON by encoding the request into an HTML-form. | |
if (options.emulateJSON) { | |
headers['Content-Type'] = 'application/x-www-form-urlencoded'; | |
params.body = params.json ? {model: params.json} : {}; | |
if (params.json) delete params.json; | |
} | |
// For older servers, emulate HTTP by mimicking the HTTP method with `_method` | |
// And an `X-HTTP-Method-Override` header. | |
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { | |
params.type = 'POST'; | |
if (options.emulateJSON) params.body._method = type; | |
headers['X-HTTP-Method-Override'] = type; | |
} | |
// When emulating JSON, we turn the body into a querystring. | |
// We do this later to let the emulateHTTP run its course. | |
if (options.emulateJSON) { | |
params.body = qs.stringify(params.body); | |
} | |
// Combine generated headers with user's headers. | |
if (options.headers) _.extend(headers, options.headers); | |
// Turn a jQuery.ajax formatted request into xhr compatible | |
params.method = params.type; | |
var ajaxSettings = _.extend(params, options); | |
// Make the request. The callback executes functions that are compatible | |
// With jQuery.ajax's syntax. | |
var _xhr = options.xhr = xhr(ajaxSettings, function (err, resp, body) { | |
if (err && options.error) return options.error(resp, 'error', err.message); | |
if (body && options.success) return options.success(body, 'success', resp); | |
}); | |
model.trigger('request', model, _xhr, options, ajaxSettings); | |
return _xhr; | |
}; | |
// Map from CRUD to HTTP for our default `Backbone.sync` implementation. | |
var methodMap = { | |
'create': 'POST', | |
'update': 'PUT', | |
'patch': 'PATCH', | |
'delete': 'DELETE', | |
'read': 'GET' | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment