Javascript issue using API with Mongoose - javascript

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)
}

Related

how can i avoid error "can't convert undefined to an object "

some of the document does not consists planDetails planId properties and its returning error "can't convert undefined to an object , but i have to fetch that document if these properties exists or not , how can i avoid this error
this.profile.find({ userId: ObjectId(req.id) }).populate("planId").lean().exec(function(err, profileFound) {
console.log(profileFound);
if (err) return callback(err);
if (profileFound && profileFound.length === 0) {
return callback(false, common.errorMsg("PROFILE DOES NOT EXIST"));
} else {
var profileData = profileFound[0];
profileData["isPlanTaken"] = false;
profileData["planDetails"] = {};
if(profileData.hasOwnProperty("planId") && profileData.planId){
if(Object.keys(profileData.planId).length>0){
profileData["isPlanTaken"]=true;
profileData["planDetails"]=profileData.planId;
}
}
return callback(
false,
common.successMsg("PROFILE FETCHED",profileData )
);
}
});
I think there was missing the initialization of profileData variable only...
const profileData = {};
profileData["isPlanTaken"] = false;
console.log(profileData);
profileData["planDetails"] = {};
if(profileData.hasOwnProperty("planId") && Object.keys(profileData.planId)){
profileData["isPlanTaken"]=true;
profileData["planDetails"]=profileData.planId;
}
console.log(profileData);
And I think that is also enough to check a property is exists in an object. Can you please give me more data for example, because I don't really know what do you need.
const profileData = {};
profileData.isPlanTaken = false;
console.log(profileData);
profileData.planId = 5; // for example
if (profileData.planId) {
profileData.isPlanTaken = true;
profileData.planDetails = profileData.planId;
}
console.log(profileData);

AngularJS make a call to the database only after the user enters one character

I created an angular material autocomplete. Everything is working fine but now I am trying to modify the code and make a call to the database only after the user enter one character in the autocomplete box. The getEmployees function is making the http call to the database. I tried this but I am getting the error that seachText is undefined. Further on I am trying to pass the first letter from the autocomplete to the getEmployees. I created a project in Plunker: https://plnkr.co/edit/gLX5Tu0Jlvxh6T7HE6O3?p=preview
if(searchText != undefined || searchText != null)
{
getEmployees().then(function (users)
{
vm.employees = employees
})
}
in your code md-item-text="item.name" is there, but 'name' key is not there in your json.. use md-item-text="item.FirstName".. it will work
The code below is a bit rough, not DRY, but it essentially works so hopefully it may point you in the right direction
angular
.module('AutocompleteApp', ['ngMaterial'])
.controller('AutocompleteController', function($scope, $http, $filter) {
var vm = this;
// data for autocomplete
vm.getMatches = function(searchText) {
if (!vm.employees) {
getEmployees().then(function(employees) {
vm.employees = employees;
var term = searchText && searchText.toLowerCase();
if (!term) {
return [];
} else {
return $filter('filter')(vm.employees, term);
}
});
} else {
var term = searchText && searchText.toLowerCase();
if (!term) {
return [];
} else {
return $filter('filter')(vm.employees, term);
}
}
};
// how we get employee data
function getEmployees() {
return $http.get('employees.json').then(function(response) {
return response.data;
}, function failureCallback(response) {
reject("Error!");
});
}
});
https://plnkr.co/edit/QfHaZ6b3vFW57KeKBLhx?p=preview

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.

API Key with colon, parsing it gives TypeError: forEach isn't a function

I'm trying to use New York Times API in order to get the Top Stories in JSON but I keep on getting a:
Uncaught TypeError: top.forEach is not a function
I feel like there's something wrong with the API key since it has : colons in the url. I even tried to encode it with %3A but it still doesn't work.
This is the basic url:
http://api.nytimes.com/svc/topstories/v2/home.json?api-key={API-KEY}
My function that grabs the data from the url:
```
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(top) {
top.forEach(function(data) {
link = data.results.url;
cardTitle = data.results.title;
if(data.results.byline == "") { postedBy = data.results.source; }
else { postedBy = data.results.byline; }
imgSource = data.results.media[0].media-metadata[10].url;
createCardElements();
});
});
}
I console.log(url) and when I click it inside Chrome console, it ignored the part of the key that comes after the colon. I've been debugging, but I can't seem to figure out the error.
Here is a version of the code that works.
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(data) {
if (data.error) {
alert('error!'); // TODO: Add better error handling here
} else {
data.results.forEach(function(result) {
var link = result.url,
cardTitle = result.title,
postedBy = result.byline == "" ? result.source : result.byline,
hasMultimedia = (result.multimedia || []).length > 0,
imgSource = hasMultimedia ? result.multimedia[result.multimedia.length - 1].url : null;
createCardElement(link, cardTitle, postedBy, imgSource);
});
}
});
}
function createCardElement(link, title, postedBy, imgSource) {
// create a single card element here
console.log('Creating a card with arguments of ', arguments);
}
topStories('http://api.nytimes.com/svc/topstories/v2/home.json?api-key=sample-key');
You are most likely going to need to do a for ... in loop on the top object since it is an object. You can not do a forEach upon on object the syntax would probably look like this:
function topStories(topStoriesURL) {
$.getJSON(topStoriesURL, function(top) {
for (var datum in top) {
link = datum.results.url;
cardTitle = datum.results.title;
if(datum.results.byline == "") { postedBy = datum.results.source; }
else { postedBy = datum.results.byline; }
imgSource = datum.results.media[0].media-metadata[10].url;
createCardElements();
});
});
}
Heres the documentation on for...in loops

Azure mobile services and Ember.js

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

Categories

Resources