Azure mobile services and Ember.js - javascript

Hello!
I learning Ember.js as Web-Client Windows Azure Mobile Services from this tutorial.
When I write:
Tothevoidjs.ApplicationRoute = Ember.Route.extend({
// admittedly, this should be in IndexRoute and not in the
// top level ApplicationRoute; we're in transition... :-)
model: function(params) {
return Tothevoidjs.Secret.findAll();
}
});
I get this error:
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, undefinedDescriptor);
o_defineProperty(this, '_super', undefinedDescriptor);
var m = meta(this), proto = m.proto;
m.proto = this;
if (initMixins) {
// capture locally so we can clear the closed over variable
var mixins = initMixins;
initMixins = null;
this.reopen.apply(this, mixins);
}
if (initProperties) {
// capture locally so we can clear the closed over variable
var props = initProperties;
initProperties = null;
var concatenatedProperties = this.concatenatedProperties;
for (var i = 0, l = props.length; i < l; i++) {
var properties = props[i];
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
for (var keyName in properties) {
if (!properties.hasOwnProperty(keyName)) { continue; }
var value = properties[keyName],
IS_BINDING = Ember.IS_BINDING;
if (IS_BINDING.test(keyName)) {
var bindings = m.bindings;
if (!bindings) {
bindings = m.bindings = {};
} else if (!m.hasOwnProperty('bindings')) {
bindings = m.bindings = o_create(m.bindings);
}
bindings[keyName] = value;
}
var desc = m.descs[keyName];
Ember.assert("Ember.Object.create no longer supports defining computed properties.", !(value instanceof Ember.ComputedProperty));
Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
Ember.assert("`actions` must be provided at extend time, not at create time, when Ember.ActionHandler is used (i.e. views, controllers & routes).", !((keyName === 'actions') && Ember.ActionHandler.detect(this)));
if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
var baseValue = this[keyName];
if (baseValue) {
if ('function' === typeof baseValue.concat) {
value = baseValue.concat(value);
} else {
value = Ember.makeArray(baseValue).concat(value);
}
} else {
value = Ember.makeArray(value);
}
}
if (desc) {
desc.set(this, keyName, value);
} else {
if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
this.setUnknownProperty(keyName, value);
} else if (MANDATORY_SETTER) {
Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
} else {
this[keyName] = value;
}
}
}
}
}
finishPartial(this, m);
this.init.apply(this, arguments);
m.proto = proto;
finishChains(this);
sendEvent(this, "init");
} has no method 'findAll'
My app.js:
var Tothevoidjs = window.Tothevoidjs = Ember.Application.create();
var client = new WindowsAzure.MobileServiceClient(
"link",
"key"
);
Tothevoidjs.WAMAdapter = Ember.Object.extend({
table: null,
init: function() {
this.table = this.get('table');
},
find: function(record, id) {
var query = this.table.where({
id: id
});
return query.read().then(function(data) {
Ember.run(record, record.load, data);
});
},
findAll: function(klass, records) {
var _self = this;
return _self.table.read().then(function(data) {
Ember.run(records, records.load, klass, data);
});
},
findQuery: function(klass, records, params) {
var query = this.table.where(params);
return query.read().then(function(data) {
Ember.run(records, records.load, klass, data);
});
},
createRecord: function(record) {
return this.table.insert(record.toJSON()).then(function(data) {
Ember.run(function() {
record.load(data.id, data);
record.didCreateRecord();
});
});
}
});
/* Order and include as you please. */
require('scripts/controllers/*');
require('scripts/store');
require('scripts/models/*');
require('scripts/routes/*');
require('scripts/views/*');
require('scripts/router');
My model file:
var attribute = DS.attr;
Tothevoidjs.Secret = DS.Model.extend({
id: attribute('number'),
body: attribute('string')
});
var client = new WindowsAzure.MobileServiceClient(
"link",
"key"
);
Tothevoidjs.Secret.adapter = Tothevoidjs.WAMAdapter.create({
table: client.getTable('secret')
});
And router:
Tothevoidjs.ApplicationRoute = Ember.Route.extend({
// admittedly, this should be in IndexRoute and not in the
// top level ApplicationRoute; we're in transition... :-)
model: function(params) {
return Tothevoidjs.Secret.findAll();
}
});
I do not understand what I did wrong. :(
Please tell me how to avoid this error or what I should read to understand it.
If you need to know version of Ember.js - it's from yeoman generator - 1.0.0
P.S. I'm newbie in web-dev.

Your tutorial is using the ember-model libray. But your current code use ember-data version 1.0.0.beta.x. Both are data libraries for ember, have similar api, but are different.
I recommend you to use the ember-model libray, so you will be able to finish the tutorial.
So, import the ember-model script, the source is here, make sure it comes after the ember.js script, and change your model definition to use ember-model:
var attribute = Ember.attr;
Tothevoidjs.Secret = Ember.Model.extend({
id: attribute('number'),
body: attribute('string')
});
I hope it helps

Related

How to get utility function from helper file on node.js server?

I have a node/express server and I'm trying to get a function from a helper file to my app.js for use. Here is the function in the helper file:
CC.CURRENT.unpack = function(value)
{
var valuesArray = value.split("~");
var valuesArrayLenght = valuesArray.length;
var mask = valuesArray[valuesArrayLenght-1];
var maskInt = parseInt(mask,16);
var unpackedCurrent = {};
var currentField = 0;
for(var property in this.FIELDS)
{
if(this.FIELDS[property] === 0)
{
unpackedCurrent[property] = valuesArray[currentField];
currentField++;
}
else if(maskInt&this.FIELDS[property])
{
//i know this is a hack, for cccagg, future code please don't hate me:(, i did this to avoid
//subscribing to trades as well in order to show the last market
if(property === 'LASTMARKET'){
unpackedCurrent[property] = valuesArray[currentField];
}else{
unpackedCurrent[property] = parseFloat(valuesArray[currentField]);
}
currentField++;
}
}
return unpackedCurrent;
};
At the bottom of that helper file I did a module.export (The helper file is 400 lines long and I don't want to export every function in it):
module.exports = {
unpackMessage: function(value) {
CCC.CURRENT.unpack(value);
}
}
Then in my app.js I called
var helperUtil = require('./helpers/ccc-streamer-utilities.js');
and finally, I called that function in app.js and console.log it:
res = helperUtil.unpackMessage(message);
console.log(res);
The problem is that the console.log gives off an undefined every time, but in this example: https://github.com/cryptoqween/cryptoqween.github.io/tree/master/streamer/current (which is not node.js) it works perfectly. So I think I am importing wrong. All I want to do is use that utility function in my app.js
The unPackMessage(val) call doesn't return anything:
module.exports = {
unpackMessage: function(value) {
CCC.CURRENT.unpack(value);
}
}
you need to return CCC.CURRENT.UNPACK(value);
module.exports = {
unpackMessage: function(value) {
return CCC.CURRENT.unpack(value);
}
}

How do I convert an array into an object within array - Angular and Javascript

What I am trying to do is take an array within an object within an array within an object (I know my data structure is ridiculous, any help with that would be great also) and convert the last array into an object with a "key":"value". I'm using Angular 1.5.7 if there is anything in Angular that could help do this. I know that probably makes no sense. I couldn't figure out a way to say what I am trying to do clearly so let me show you:
I start with an object like this:
{"instructor":[{"instructor_emails":[ "test#test.com","tester#tester.com"]}]}
And I want it to be:
{"instructor":[{"instructor_emails":{ "email":"test#test.com","email":"tester#tester.com"}}]}
I tried a couple of things and the closest I found was:
instructor.instructor_emails.map(function(e) {
return { email: e };
});
But it doesn't quite do what I'm trying to do... Any thoughts?
This was correct all along (Thanks Alex)
instructor.instructor_emails.map(function(e) {
return { email: e };
});
Returns:
{instructor:[instructor_emails[{"email":"example1#example1.com",{"email":"example1#example1.com"}]]}
The data structure is still ridiculous but it will suffice for what I am trying to do
You should read up on Object-oriented programming for optimal data storage, particularly concerning classes. To transition between traditional OOP languages, like Java, to JavaScript you can use TypeScript.
Below is a snippet i created using TypeScript:
/// <reference path="definitions/jquery.d.ts" />
console.clear();
var Instructor = (function () {
function Instructor(name, emails) {
if (name === void 0) { name = ""; }
if (emails === void 0) { emails = []; }
this.name = name;
this.emails = emails;
}
Instructor.prototype.addEmail = function (email) {
if (email === void 0) { email = ""; }
//Run validation
if (email.length > 3) {
this.emails.push(email);
}
};
Instructor.prototype.getEmails = function (type) {
if (type === void 0) { type = "array"; }
var self = this;
type = type.toLowerCase();
var getEmails = {
string: function () {
return self.emails.join(" ");
},
object: function () {
return self.emails.map(function (e) {
return { email: e };
});
}
};
if (getEmails[type] === void 0) {
return this.emails;
}
else {
return getEmails[type]();
}
};
return Instructor;
}());
var instructors = [
new Instructor("Michael Bennet I", ["test#test.com", "tester#tester.com"]),
new Instructor("Michael Bennet II", ["test#test.com", "tester#tester.com"]),
];
console.log('array', instructors[0].getEmails());
console.log('object', instructors[0].getEmails("object"));
console.log('string', instructors[0].getEmails("String"));
/*
// This is TypeScript
class Instructor {
constructor(public name: string = "", public emails: string[] = []) {
}
public addEmail(email: string = "") {
//Run validation
if (email.length > 3) {
this.emails.push(email);
}
}
public getEmails(type: string = "array") {
var self = this;
type = type.toLowerCase();
var getEmails = {
string: function () {
return self.emails.join(" ");
},
object: function () {
return self.emails.map(function (e) {
return { email: e };
});
}
}
if (getEmails[type] === void 0) {
return this.emails;
} else {
return getEmails[type]();
}
}
}
var instructors: Instructor[] = [
new Instructor("Michael Bennet I", ["test#test.com", "tester#tester.com"]),
new Instructor("Michael Bennet II", ["test#test.com", "tester#tester.com"]),
];
console.log('array',instructors[0].getEmails());
console.log('object',instructors[0].getEmails("object"));
console.log('string',instructors[0].getEmails("String"));
<p>Object can have their own functions to "get" data they contain in unique ways.</p>
<p>This way, you can get the same data in several different ways</p>

Return a promise with a model and a service

I have an error with a promise.
I try to use angular-tree-dnd , but I have a problem with a promise.
from my controller :
project.getAll().then(function(results) {
var projects = results;
$scope.results = [];
angular.forEach(projects, function(result) {
$scope.results.push(project.build(result));
});
return $scope.results;
});
$scope.tree_data = $TreeDnDConvert.line2tree($scope.results, 'id', 'ParentId');
my model :
var Project = function(properties) {
// Model
this.description = null;
this.file = null;
this.name = null;
this.ParentId = null;
this.path = null;
angular.extend(this, properties);
};
Project.prototype.setModel = function(obj) {
angular.extend(this, obj);
};
Project.prototype.getAll = function() {
return ProjectService.getAll();
};
Project.prototype.build = function(data) {
var project = new Project(data);
return project;
};
my service (with $webSql) :
this.getAll = function(params) {
var projects = [];
return db.selectAll('projects').then(function(results) {
for (var i = 0; i < results.rows.length; i++) {
projects.push(results.rows.item(i));
}
return projects;
});
};
I have no error but my home is empty.
I tried this :
project.getAll().then(function(results) {
var projects = results;
$scope.results = [];
angular.forEach(projects, function(result) {
$scope.results.push(project.build(result));
});
return $scope.results;
}).then(function(array) {
$scope.tree_data = $TreeDnDConvert.line2tree(array, 'id', 'ParentId');
});
But I have this error :
angular.min.js:13550 TypeError: Cannot read property '__children__' of undefined
at Object._$initConvert.line2tree (ng-tree-dnd.js:1456)
I think that my array is empty
I suspect that this is the root of your problem:
"ParentId":"null"
Both of the items on your tree have a ParentId with the string value "null". This probably means that the dnd library is looking for a node with an ID of "null", finding nothing, and trying to access the __children__ property on that undefined value.
The solution: fix the data in your DB so that the parent IDs are actually null values and not the value "null".
Good evening)
Please set a breakpoint, or use debugger, alert, console.log with JSON.stringify(array), before your last operation:
$scope.tree_data = $TreeDnDConvert.line2tree(array, 'id', 'ParentId')
(last version with then and error).
I think you got correct array and trouble not in promises, but in line2tree syntax.

Javascript issue using API with Mongoose

I am creating a simple AngularJS SPA and using API to connect to Mongoose. But I keep getting the following error when simply trying to add a new member, the member does actually add to mongoose but will not be seen on my webpage until I refresh. And when I press the Add Member button I get the following error in Google Chrome Dev Tools:
TypeError: Cannot read property 'success' of undefined
at Scope.$scope.addMember (app.js:195)
I have no idea how to get around it. Here is my app.js
app.controller('MembersController', ['$scope','SimpleFactory',
function ($scope,SimpleFactory) {
SimpleFactory.getMembers()
.success(function(members) {
$scope.members = members;
});
$scope.addMember = function()
{
var member = {
name: $scope.newMember.name,
address: $scope.newMember.address,
age : $scope.newMember.age,
level : $scope.newMember.level,
swimmer : $scope.newMember.swimmer,
email : $scope.newMember.email,
regdate : $scope.newMember.regdate,
}
SimpleFactory.addMember(member)
.success(function(added_member)
{
$scope.members.push(added_member);
$scope.newMember = { }
} );
}
$scope.membNoInRange = function ()
{
return $scope.memberNo && $scope.memberNo >=0
&& $scope.memberNo < $scope.members.length
}
}])
Adding in my factory service:
app.factory('SimpleFactory', ['$http', function($http){
var members = $http.get('/api/members')
factory.getMembers = function ()
{
return members = $http.get('/api/members');
}
factory.getMember = function (index) {
if (index >=0 && index < members.length ) {
return members = $http.get('/api/members/' + member_id )
}
return undefined
}
factory.addMember = function(member) {
$http.post('/api/members',member)
}
factory.updateMember = function(index,member) {
$http.put('/api/members/' + member_id, member)
}
return factory;
}])
Can anyone help, do I need to provide more information?
The functions of the service are not returning a promise.
Try adding return before the $http...
factory.addMember = function(member) {
return $http.post('/api/members', member)
}
factory.updateMember = function(index,member) {
return $http.put('/api/members/' + member_id, member)
}

Publish/Subscribe to notification after published

I am trying to understand the Observable/Observer design pattern.
This is the code I have so far (code from Javascript Patterns book):
var publisher = {
subscribers: {
any: [] // event type: subscribers
},
publications: {
any: []
},
subscribe: function (fn, type) {
type = type || 'any';
if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
if(typeof this.publications[type] === "undefined"){
return;
}
var pubs = this.publications[type],
i,
max = pubs.length
for(i = 0;i<max;i++){
this.subscribers[type][i](pubs[i]);
}
},
unsubscribe: function (fn, type) {
this.visitSubscribers('unsubscribe', fn, type);
},
publish: function (publication, type) {
var pubtype = type || 'any';
this.visitSubscribers('publish', publication, type);
if(typeof this.publications[pubtype] === "undefined") {
this.publications[pubtype] = [];
}
this.publications[pubtype].push(publication);
},
visitSubscribers: function (action, arg, type) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max;
if(typeof subscribers === 'undefined') {
return;
}
max = subscribers.length;
for (i = 0; i < max; i += 1) {
if (action === 'publish') {
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
subscribers.splice(i, 1);
}
}
}
}
};
function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
o.publications = {any: []};
}
var paper = {
daily: function () {
this.publish("big news today");
},
monthly: function () {
this.publish("interesting analysis", "monthly");
},
yearly: function () {
this.publish("every year","yearly");
}
};
makePublisher(paper);
var joe = {
drinkCoffee: function (paper) {
console.log('Just read ' + paper);
},
sundayPreNap: function (monthly) {
console.log('About to fall asleep reading this ' + monthly);
},
onHolidays: function(yearly) {
console.log('Holidays!'+yearly);
}
};
paper.daily();
paper.monthly();
paper.yearly();
paper.subscribe(joe.drinkCoffee);
paper.subscribe(joe.onHolidays,'yearly');
paper.subscribe(joe.sundayPreNap, 'monthly');
I wonder if it is possible somehow to allow clients to receive the notifications
even if they registered themselves after such notifications had been broadcast.
Should I modify the publisher.subscribe and make it check if undefined and if yes publish the event type?
Thanks in advance.
*EDIT 1 *
I've added a publications object to save the publications in the publish function. I also check if there are subscribers for the publication type and if not I call return. Now I need to figure out how to notify them for older publication on subscribe.
*EDIT 2 *
New version of a working script added. Is it thought correct or the best way to do it?
If you want to allow subscribers to get the notifications after they are sent, what you need to do is just
For each different publication type, keep a list of all notifications you get for it.
(When publishing, add the publication to the appropriate list)
Change the subscribe function so that it also sends all the appropriate stored notifications to the late-arriving subscriber.
2.1 Perhaps you should also create a separate send_notification_to(arg, type, subscriber) method, to avoid code duplicatio with visitSubscribers

Categories

Resources