Skip to content

Instantly share code, notes, and snippets.

@JemiloII
Last active August 29, 2015 14:06
Show Gist options
  • Save JemiloII/3da234ede1215b34ac80 to your computer and use it in GitHub Desktop.
Save JemiloII/3da234ede1215b34ac80 to your computer and use it in GitHub Desktop.
(function() {
/*global Ember*/
/*global DS*/
/*global io*/
'use strict';
var RSVP = Ember.RSVP;
var get = Ember.get;
DS.SailsRESTAdapter = DS.RESTAdapter.extend({
defaultSerializer: '-json',
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 {
console.log(error);
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) {
console.log(err.message);
return err.message;
});
console.log(memo);
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');
console.log({
error: data.error,
model: data.model,
summary: data.summary,
status: data.status
});
return !!(data.error && data.model && data.summary && data.status);
},
ajax: function(url, method, data) {
console.log('ajax');
console.log('method: '+ method);
console.log(data);
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;
}
});
})();
<h2>Edit {{type}}: {{username}}</h2>
{{view Ember.TextField type="hidden" value=id}}
{{input value=username}}
{{view Ember.Select
content=types
value=type
selectionBinding="model.type"
prompt="Account type"
}}
<button {{action update target="controller"}} >Submit</button>
<h2>Members</h2>
<nav>{{#link-to 'members.new'}}New{{/link-to}}</nav>
{{#each}}
<p>{{#link-to 'members.show' id}} {{type}}: {{username}} {{/link-to}}</p>
{{/each}}
App.Member = DS.Model.extend({
username: DS.attr('string'),
type: DS.attr('string'),
createdAt: DS.attr('date'),
updatedAt: DS.attr('date')
});
App.MembersEditController = Ember.ObjectController.extend({
types: [
"Member",
"Creator",
"Producer",
"Moderator",
"Administer"
],
actions: {
update: function(params){
this.get("model").save();
this.transitionToRoute('members.show', this.get('model.id'));
}
}
});
App.MembersEditRoute = Ember.DSModelRoute.extend({
model: function(params){
return this.store.find('member', params.member_id);
},
setupController : function(controller, model, params){
controller.set("model", model);
}
});
App.MembersIndexRoute = Ember.Route.extend({
model: function(){
return this.store.find('member');
}
});
App.MembersNewController = Ember.ObjectController.extend({
selectedType: "Member",
types: [
"Member",
"Creator",
"Producer",
"Moderator",
"Administer"
],
actions: {
create: function(){
// console.log('ADDED NEW MEMBER');
// console.log("Username: "+this.get('model.username') + " Type: " +this.get('model.type'));
// console.log({username: this.get('model.username'), type: this.get('model.type')});
this.get('model').save().then(function () {
self.transitionToRoute('members.index');
});
this.transitionToRoute('members.index');
}
}
});
App.MembersNewRoute = Ember.DSModelRoute.extend({
model: function(){
return this.store.createRecord('member');
},
setupController : function(controller, model){
controller.set("model", model);
}
});
<h2>New Member</h2>
<p>{{model.username}} {{model.type}}</p>
{{input
name="username"
placeholder="Enter Username..."
value="username"
}}
{{view Ember.Select
content=types
value=selectedType
selectionBinding="model.type"
prompt="Account type"
}}
<button {{action create target="controller"}} >Submit</button>
<h2>{{username}}</h2>
<h3>{{type}}</h3>
{{#link-to 'members.edit' id}}Edit{{/link-to}}
{{#link-to 'members'}}Back{{/link-to}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment