//MMM... Minimal Metal Models for JavaScript //Usage example of an MMM model var geobit = new Geobit({longitude: 90, latitude: 70}); geobit.save( function(model){ if(model.error.message){ alert('big douche!'); }else{ alert('big success!'); } } ); //Implementation of a sample Model function Geobit(options){ mmm.Model.call(options); this.addField('longitude'); this.addField('latitude'); this.addField('raw'); this.addField('acl_token'); } Geobit.prototype = new mmm.Model; Geobit.constructor = Geobit; //not all REST api's are equal Geobit.prototype.save = function(success, failure){ var that = this; var method; var url; var fields; var body = {}; if(this.getField('id')===undefined){ method = 'POST'; url = '/api/1.0/geobits'; fields = ['raw', 'longitude', 'latitude', 'parent_id']; for(var postField in postFields){ var field = this.getField(postField); if(field!==undefined){ body[postField] = field; } } }else{ method = 'PUT'; url = '/api/1.0/geobits/' + this.getField('id'); fields = ['raw', 'longitude', 'latitude', 'parent_id', 'acl_token'] for(var putField in putFields){ var field = this.getField(putField); if(field!==undefined){ body[putField] = field; } } } GeobaconRESTAdapter.request(url, method, function(response){ Geobit.setFieldsFromResponse(model, response); }, {body: body} ); }; //static helper for popluting model objects from a pre-formatted response Geobit.setFieldsFromResponse = function(model, response){ if('error' in response){ model.error = response.error; return; } if(response.id){ model.setField('id', response.id); } var properties = response.properties; if(properties){ model.setField('raw', properties.raw); model.setField('parent_id', properties.parent_id); model.setField('acl_token', properties.acl_token); } var geometry = response.geometry; if(geometry && geometry.coordinates){ var coordinates = geometry.coordinates; model.setField('longitude', coordinates[0]); model.setField('latitude', coordinates[1]); } }; //retrieve a single item Geobit.get = function(id, longitude, latitude, distance, callback){ var url; var getParams; var path = '/api/1.0/geobits' + id; var params = { longitude: longitude, latitude: latitude, distance: distance }; var model = new Geobit(); for(var param in params){ getParams += (getParams) ? '&' : ''; getParams += encodeURIComponent(param) + '=' + encodeURIComponent(params[param]); } url = path + '?' + getParams; GeobaconRestAdapter.request(url, 'GET', function(response){ Geobit.setFieldsFromResponse(model, response); callback(model); }); }; //simple adapater for making XHR requests and handling responses var GeobaconRESTAdapter = { hostname: 'http://geobacon.com', request: function(url, method, callback, options){ var body = {}; var options = options || {}; var url = this.hostname + path; if(options.body && (method=='POST' || method=='PUT')){ body = options.body; } var xhr = $.ajax(url, { type: method, data: body, complete: function(xhr){ GeobaconRESTAdapter.response(xhr, callback); } }); }, response: function(xhr, callback){ var envelope = {}; try { envelope = JSON.parse(xhr.responseText); }catch(e){ envelope = {error: {message: 'Could not process request', params: []}}; } callback(envelope); } };