-
Notifications
You must be signed in to change notification settings - Fork 2
/
restful.js
114 lines (92 loc) · 3.74 KB
/
restful.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
PORT of Backbone.sync for Alloy
BY JOHN WRIGHT (WRIGHTLABS)
https://github.com/wrightlabs/alloy.sync.restful
Override this function to change the manner in which Backbone persists models to the server.
You will be passed the type of request, and the model in question.
By default, makes a RESTful http request (using Titanium.Network.HTTPClient) to the model's url().
********* WARNING, THE FOLLOWING HAS NEVER BEEN TESTED IN ALLOY *************
Turn on Backbone.emulateHTTP in order to send PUT and DELETE requests as POST,
with a _method parameter containing the true HTTP method,
as well as all requests with the body as application/x-www-form-urlencoded
instead of application/json with the model in a param named model.
Useful when interfacing with server-side languages like PHP
that make it difficult to read the body of PUT requests.
*****************************************************************************
*/
module.exports.sync = function(method, model, options) {
var methodMap = {
'create': 'POST',
'update': 'PUT',
'delete': 'DELETE',
'read': 'GET'
};
var type = methodMap[method];
//Default options, unless specified.
options || (options = {});
//Default JSON-request options.
var params = {type: type, dataType: 'json'};
if(!options.timeout) {
params.timeout = 7000;
}
//Ensure that we have a URL.
if (!options.url) {
params.url = getValue(model, 'url') || urlError();
}
//Ensure that we have the appropriate request data.
if (!options.data && model && (method == 'create' || method == 'update')) {
params.contentType = 'application/json';
params.data = JSON.stringify(model.toJSON());
}
// HAS NOT BEEN TESTED IN ALLOY
//For older servers, emulate JSON by encoding the request into an HTML-form.
if (Alloy.Backbone.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model: params.data} : {};
}
// HAS NOT BEEN TESTED IN ALLOY
//For older servers, emulate HTTP by mimicking the HTTP method with _method And an X-HTTP-Method-Override header.
if (Alloy.Backbone.emulateHTTP) {
if (type === 'PUT' || type === 'DELETE') {
if (Alloy.Backbone.emulateJSON) params.data._method = type;
params.type = 'POST';
params.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
};
}
}
//Don't process data on a non-GET request.
if (params.type !== 'GET' && !Alloy.Backbone.emulateJSON) {
params.processData = false;
}
//Make the HTTPClient
var client = Ti.Network.createHTTPClient(_.extend(params, options));
client.onload = function() {
options.success(JSON.parse(this.responseText), this.status);
Ti.API.debug('[alloy.sync.restful] model:' + model.url() +' response:' + this.responseText );
};
client.onerror = function(e){
options.error(model, e.error);
Ti.API.error('[alloy.sync.restful] ERROR model:' + model.url() +' message:' + e.error );
};
// Prepare the connection.
client.open(params.type, params.url);
// Make sure content type is set.
if(params.contentType) {
params.headers['Content-Type'] = params.contentType;
}
// Set request headers found in params
for (var header in params.headers) {
client.setRequestHeader(header, params.headers[header]);
}
// Send the request.
client.send(params.data || null);
};
var getValue = function(object, prop) {
if (!(object && object[prop])) return null;
return _.isFunction(object[prop]) ? object[prop]() : object[prop];
};
//Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
Ti.API.error('[alloy.sync.restful] urlError: ' + this.responseText);
};