Last active
April 27, 2017 11:18
-
-
Save yeco/5594217 to your computer and use it in GitHub Desktop.
Rest API Adapter for Titanium Alloy
This file contains hidden or 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
/** | |
* Rest API Adapter for Titanium Alloy | |
*/ | |
function S4() { | |
return ((1 + Math.random()) * 65536 | 0).toString(16).substring(1); | |
} | |
function guid() { | |
return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4(); | |
} | |
function InitAdapter(config) { | |
return {}; | |
} | |
function apiCall(_options, _callback) { | |
var xhr = Ti.Network.createHTTPClient({ | |
timeout : 5000 | |
}); | |
//Prepare the request | |
xhr.open(_options.type, _options.url); | |
xhr.onload = function() { | |
_callback({ | |
success: true, | |
status: xhr.status == 200 ? "ok" : xhr.status, | |
code: xhr.status, | |
responseText : xhr.responseText || null, | |
responseData : xhr.responseData || null | |
}); | |
}; | |
//Handle error | |
xhr.onerror = function(e) { | |
_callback({ | |
success: false, | |
status: "error", | |
code: xhr.status, | |
data: e.error, | |
responseText : xhr.responseText | |
}); | |
Ti.API.error('[REST API] apiCall ERROR: ' + xhr.responseText) | |
} | |
for (var header in _options.headers) { | |
xhr.setRequestHeader(header, _options.headers[header]); | |
} | |
if (_options.beforeSend) { | |
_options.beforeSend(xhr); | |
} | |
xhr.send(_options.data || null); | |
} | |
function Sync(method, model, opts) { | |
var DEBUG = model.config.debug; | |
var methodMap = { | |
'create' : 'POST', | |
'read' : 'GET', | |
'update' : 'PUT', | |
'delete' : 'DELETE' | |
}; | |
var type = methodMap[method]; | |
var params = _.extend({}, opts); | |
params.type = type; | |
//set default headers | |
params.headers = params.headers || {}; | |
// We need to ensure that we have a base url. | |
if (!params.url) { | |
params.url = (model.config.URL || model.url()); | |
if (!params.url) { | |
Ti.API.error("[REST API] ERROR: NO BASE URL"); | |
return; | |
} | |
} | |
// 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.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 (Alloy.Backbone.emulateHTTP) { | |
if (type === 'PUT' || type === 'DELETE') { | |
if (Alloy.Backbone.emulateJSON) | |
params.data._method = type; | |
params.type = 'POST'; | |
params.beforeSend = function(xhr) { | |
params.headers['X-HTTP-Method-Override'] = type | |
}; | |
} | |
} | |
//json data transfers | |
params.headers['Content-Type'] = 'application/json'; | |
if(DEBUG){ | |
Ti.API.debug("[REST API] REST METHOD: " + method); | |
} | |
switch(method) { | |
case 'delete' : | |
if (!model.id) { | |
params.error(null, "MISSING MODEL ID"); | |
Ti.API.error("[REST API] ERROR: MISSING MODEL ID"); | |
return; | |
} | |
params.url = params.url + '/' + model.id; | |
if(DEBUG){ | |
Ti.API.info("[REST API] options: "); | |
Ti.API.info(params); | |
} | |
apiCall(params, function(_response) { | |
if (_response.success) { | |
var data = JSON.parse(_response.responseText); | |
if(DEBUG){ | |
Ti.API.info("[REST API] server delete response: "); | |
Ti.API.debug(data) | |
} | |
params.success(null, _response.responseText); | |
model.trigger("fetch"); | |
// fire event | |
} else { | |
params.error(JSON.parse(_response.responseText), _response.responseText); | |
Ti.API.error('[REST API] DELETE ERROR: '); | |
Ti.API.error(_response); | |
} | |
}); | |
break; | |
case 'create' : | |
// convert to string for API call | |
params.data = JSON.stringify(model.toJSON()); | |
if(DEBUG){ | |
Ti.API.info("[REST API] options: "); | |
Ti.API.info(params); | |
} | |
apiCall(params, function(_response) { | |
if (_response.success) { | |
var data = JSON.parse(_response.responseText); | |
if(DEBUG){ | |
Ti.API.info("[REST API] server create response: "); | |
Ti.API.debug(data) | |
} | |
//Rest API should return a new model id. | |
if (data.id == undefined) { | |
data.id = guid(); | |
//if not - create one | |
} | |
params.success(data, JSON.stringify(data)); | |
model.trigger("fetch"); | |
// fire event | |
} else { | |
params.error(JSON.parse(_response.responseText), _response.responseText); | |
Ti.API.error('[REST API] CREATE ERROR: '); | |
Ti.API.error(_response); | |
} | |
}); | |
break; | |
case 'update' : | |
if (!model.id) { | |
params.error(null, "MISSING MODEL ID"); | |
Ti.API.error("[REST API] ERROR: MISSING MODEL ID"); | |
return; | |
} | |
// setup the url & data | |
params.url = params.url + '/' + model.id; | |
params.data = JSON.stringify(model.toJSON()); | |
if(DEBUG){ | |
Ti.API.info("[REST API] options: "); | |
Ti.API.info(params); | |
} | |
apiCall(params, function(_response) { | |
if (_response.success) { | |
var data = JSON.parse(_response.responseText); | |
if(DEBUG){ | |
Ti.API.info("[REST API] server update response: "); | |
Ti.API.debug(data) | |
} | |
params.success(data, JSON.stringify(data)); | |
model.trigger("fetch"); | |
} else { | |
params.error(JSON.parse(_response.responseText), _response.responseText); | |
Ti.API.error('[REST API] UPDATE ERROR: '); | |
Ti.API.error(_response); | |
} | |
}); | |
break; | |
case 'read': | |
if (model.id) { | |
params.url = params.url + '/' + model.id; | |
} | |
if (params.urlparams) { | |
params.url += "?" + encodeData(params.urlparams); | |
} | |
if(DEBUG){ | |
Ti.API.info("[REST API] options: "); | |
Ti.API.info(params); | |
} | |
apiCall(params, function(_response) { | |
if (_response.success) { | |
var data = JSON.parse(_response.responseText); | |
if(DEBUG){ | |
Ti.API.info("[REST API] server read response: "); | |
Ti.API.debug(data) | |
} | |
var values = []; | |
model.length = 0; | |
for (var i in data) { | |
var item = {}; | |
item = data[i]; | |
if (item.id == undefined) { | |
item.id = guid(); | |
} | |
values.push(item); | |
model.length++; | |
} | |
params.success((model.length === 1) ? values[0] : values, _response.responseText); | |
model.trigger("fetch"); | |
} else { | |
params.error(JSON.parse(_response.responseText), _response.responseText); | |
Ti.API.error('[REST API] READ ERROR: '); | |
Ti.API.error(_response); | |
} | |
}) | |
break; | |
} | |
}; | |
var encodeData = function(obj) { | |
var str = []; | |
for (var p in obj) | |
str.push(Ti.Network.encodeURIComponent(p) + "=" + Ti.Network.encodeURIComponent(obj[p])); | |
return str.join("&"); | |
} | |
//we need underscore | |
var _ = require("alloy/underscore")._; | |
//until this issue is fixed: https://jira.appcelerator.org/browse/TIMOB-11752 | |
var Alloy = require("alloy"), Backbone = Alloy.Backbone; | |
module.exports.sync = Sync; | |
module.exports.beforeModelCreate = function(config, name) { | |
config = config || {}; | |
InitAdapter(config); | |
return config; | |
}; | |
module.exports.afterModelCreate = function(Model, name) { | |
Model = Model || {}; | |
Model.prototype.config.Model = Model; | |
return Model; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I tried the the code in the same way. But when i tried to fetch the json returned, i get an empty object in the controller. I used to get the Json object in the controller directly without using the model.. Can you help me? Do in need to send the params to login using api in the model?? Please reply.
Used the same restapi.js and model described here. In controller i had earlier used as
var loginReq = Titanium.Network.createHTTPClient();
var params = {
username : $.email.value,
password : $.password.value,
api: true,
type: 'P'
};
loginReq.onload = function() {
var response = JSON.parse(this.responseText);
var w=Alloy.createController('signedin').getView().open();
}
loginReq.onerror = function() {
alert(this.responseText);
}
loginReq.open("POST", "http://www.xxxx.com/api/login/");
loginReq.send(params);
and i'd obtained th correct json.