-
-
Save yeco/5594217 to your computer and use it in GitHub Desktop.
/** | |
* 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; | |
}; |
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.
RestAPI Sync Adapter for Titanium Alloy Framework.
How To Use
Simple add the following to your model in
PROJECT_FOLDER/app/models/
.Then add the
restapi.js
toPROJECT_FOLDER/app/assets/alloy/sync/
. Create the folders if they dont exist.Use the
debug
property in the above example to get logs printed with server response to debug your usage of the restapi adapter.