Skip to content

Instantly share code, notes, and snippets.

@JemiloII
Created August 28, 2014 20:29
Show Gist options
  • Save JemiloII/0db9a6c710e9bd6c06d3 to your computer and use it in GitHub Desktop.
Save JemiloII/0db9a6c710e9bd6c06d3 to your computer and use it in GitHub Desktop.
My ember-data.sails-adapter.js
(function() {
/*global Ember*/
/*global DS*/
/*global io*/
'use strict';
var RSVP = Ember.RSVP;
var get = Ember.get;
DS.SailsRESTAdapter = DS.RESTAdapter.extend({
//defaultSerializer: '-default',
ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
var data = Ember.$.parseJSON(jqXHR.responseText);
if (data.errors) {
return new DS.InvalidError(this.formatError(data));
} else {
return error;
}
},
/*
Sails error objects look something like this:
error: "E_VALIDATION",
model: "User",
summary: "1 attribute is invalid",
status: 400,
invalidAttributes: {
name: [
{
rule: "minLength",
message: "Validation error: "bar" Rule "minLength(10)" failed."
}
]
}
*/
formatError: function(error) {
return Object.keys(error.invalidAttributes).reduce(function(memo, property) {
memo[property] = error.invalidAttributes[property].map(function(err) {
return err.message;
});
return memo;
}, {});
},
pathForType: function(type) {
var camelized = Ember.String.camelize(type);
return Ember.String.singularize(camelized);
}
});
DS.SailsSocketAdapter = DS.SailsRESTAdapter.extend({
useCSRF: false,
CSRFToken: '',
listeningModels: {},
init: function () {
this._super();
if(this.useCSRF) {
io.socket.get('/csrfToken', function response(tokenObject) {
this.CSRFToken = tokenObject._csrf;
}.bind(this));
}
},
isErrorObject: function(data) {
console.log('isErrorObject');
return !!(data.error && data.model && data.summary && data.status);
},
ajax: function(url, method, data) {
console.log('ajax');
console.log('method: '+ method);
if(data && data.hasOwnProperty('data')){
data = data.data;
}
return this.socket(url, method, data);
},
socket: function(url, method, data) {
console.log('socket');
console.log('url: '+url+'\n method: '+method+'\n data: '+data);
var isErrorObject = this.isErrorObject.bind(this);
method = method.toLowerCase();
var adapter = this;
adapter._log(method, url, data);
if(method !== 'get')
this.checkCSRF(data);
return new RSVP.Promise(function(resolve, reject) {
io.socket[method](url, data, function (data) {
if (isErrorObject(data)) {
adapter._log('error:', data);
if (data.errors) {
reject(new DS.InvalidError(adapter.formatError(data)));
} else {
reject(data);
}
} else {
resolve(data);
}
});
});
},
buildURL: function(type, id) {
console.log('buildURL');
this._listenToSocket(type);
return this._super.apply(this, arguments);
},
_listenToSocket: function(model) {
console.log('_listenToSocket');
if(model in this.listeningModels) {
return;
}
var self = this;
var store = this.container.lookup('store:main');
var socketModel = model;
function findModelName(model) {
console.log('findModelName');
var mappedName = self.modelNameMap[model];
console.log('findModelName model: '+model);
return mappedName || model;
}
function pushMessage(message) {
console.log('pushMessage');
var type = store.modelFor(socketModel);
console.log('Type: '+ type);
console.log('Typekey: '+ typekey);
var serializer = store.serializerFor(type.typeKey);
// Messages from 'created' don't seem to be wrapped correctly,
// however messages from 'updated' are, so need to double check here.
if(!(model in message.data)) {
var obj = {};
obj[model] = message.data;
message.data = obj;
}
var record = serializer.extractSingle(store, type, message.data);
console.log('pushMessage var Record: '+ record);
store.push(socketModel, record);
}
function destroy(message) {
var type = store.modelFor(socketModel);
var record = store.getById(type, message.id);
if ( record && typeof record.get('dirtyType') === 'undefined' ) {
record.unloadRecord();
}
}
var eventName = Ember.String.camelize(model).toLowerCase();
io.socket.on(eventName, function (message) {
// Left here to help further debugging.
console.log("Got message on Socket : " + JSON.stringify(message));
if (message.verb === 'created') {
// Run later to prevent creating duplicate records when calling store.createRecord
Ember.run.later(null, pushMessage, message, 50);
}
if (message.verb === 'updated') {
pushMessage(message);
}
if (message.verb === 'destroyed') {
destroy(message);
}
});
// We add an emtpy property instead of using an array
// ao we can utilize the 'in' keyword in first test in this function.
this.listeningModels[model] = 0;
},
_log: function() {
if (this.log) {
console.log.apply(console, arguments);
}
},
checkCSRF: function(data) {
if(!this.useCSRF) return data;
if(this.CSRFToken.length === 0) {
throw new Error("CSRF Token not fetched yet.");
}
/* jshint ignore:start */
data['_csrf'] = this.CSRFToken;
/* jshint ignore:end */
return data;
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment