Share updated variable with factory (variable scope) - javascript

I would like to share an updated variable (updated from a function) through a factory (Angularjs)
I have the following factory:
appTspSrv.factory('shared', function(db) {
var entities;
var getEntities = function(){
db.query('getEntities', function(err, doc) {
if (err) {
console.log(err);
} else {
entities = doc.rows;
}
});
};
getEntities();
return {
getEntities: function() {
return entities;
}
}
});
When I call my factory's function from the controller I get 'undifined':
console.log(shared.getEntities());
Why is that and how can I fix this?

Related

Make multiple callbacks from node js asynchronous function

How can I return a object of data returned by asynchronous function called multiple times from within a asynchronous function.
I'm trying to implement like this :
var figlet = require('figlet');
function art(dataToArt, callback)
{
var arry[];
figlet(dataToArt, function(err, data) {
if (err) {
console.log('Something went wrong...');
console.dir(err);
return callback('');
}
arry[0] = data;
callback(arry);
});
figlet(dataToArt, function(err, data) {
if (err) {
console.log('Something went wrong...');
console.dir(err);
return callback('');
}
arry[1] = data;
callback(arry);
});
}
art('Hello World', function (data){
console.log(data);
});
How can I do it correctly, I searched and searched but couldn't find a solution.
Ps. I'm using Figlet.js
I don't know if you're ok using an external module, but you can use tiptoe.
Install it using npm install tiptoe like any regular module and it basically goes like this:
var tiptoe = require('tiptoe')
function someAsyncFunction(obj, callback) {
// something something
callback(null, processedData);
}
tiptoe(
function() {
var self = this;
var arr = ['there', 'are', 'some', 'items', 'here'];
arr.forEach(function(item) {
someAsyncFunction(item, self.parallel());
});
},
function() {
var data = Array.prototype.slice.call(arguments);
doSomethingWithData(data, this);
},
function(err) {
if (err) throw (err);
console.log('all done.');
}
);
the someAsyncFunction() is the async function you want to call does something and calls the callback parameter as a function with the parameters error and data. The data parameter will get passed as an array item to the following function on the tiptoe flow.
Did it Myself :) Thanks to mostafa-samir's post
var figlet = require('figlet');
function WaterfallOver(list, iterator, callback) {
var nextItemIndex = 1;
function report() {
nextItemIndex++;
if(nextItemIndex === list.length)
callback();
else
iterator([list[0],list[nextItemIndex]], report);
}
iterator([list[0],list[1]], report);
}
var FinalResult = [];
WaterfallOver(["hello","Standard","Ghost"], function(path, report) {
figlet.text(path[0], { font: path[1] }, function(err, data) {
if (err) {
FinalResult.push("Font name error try help");
report();
return;
}
data = '<pre>.\n' + data + '</pre>';
FinalResult.push(data);
report();
});
}, function() {
console.log(FinalResult[0]);
console.log(FinalResult[1]);
});

Callback is not a function in mongoose.find({})

I am new to Node.js and mongoose, i am trying to query objects from a mongo collection using find({}) and the function is as follows :
schema.statics.listAllQuizes = function listAllQuizes(){
Model.find({},function(err,quizes,cb){
if(err){
return cb(err);
}else if(!quizes){
return cb();
}
else {
return cb(err,quizes);
}
});};
But when i call this function i get an error saying
return cb(err,quizes);
^
TypeError: cb is not a function
I am stuck at this point, can someone please help me with this, thanks in advance.
The callback should an argument to listAllQuizes, not an argument to the anonymous handler function.
In other words:
schema.statics.listAllQuizes = function listAllQuizes(cb) {
Model.find({}, function(err, quizes) {
if (err) {
return cb(err);
} else if (! quizes) {
return cb();
} else {
return cb(err, quizes);
}
});
};
Which, logically, is almost the same as this:
schema.statics.listAllQuizes = function listAllQuizes(cb) {
Model.find({}, cb);
};
Here's an example on how to use it:
var quiz = App.model('quiz');
function home(req, res) {
quiz.listAllQuizes(function(err, quizes) {
if (err) return res.sendStatus(500);
for (var i = 0; i < quizes.length; i++) {
console.log(quizes[i].quizName)
}
res.render('quiz', { quizList : quizes });
});
}
Assuming you have code somewhere that looks like this:
foo.listAllQuizzes(function (err, quizzes) {
...
});
Then your function listAllQuizzes is passed a callback:
schema.statics.listAllQuizzes = function (cb) {
Model.find({}, function(err, quizzes) {
if (err) return cb(err);
cb(null, quizzes);
});
};

How do I pass data from angular post to web api post

I have an angular post method through which I want to pass data to web api post but doesn't seem to work.
What could I be doing wrong?
customerPersistenceService.js
var customerPersistenceService = function ($http, $q) {
return {
save: function(customer) {
var deferred = $q.defer();
$http.post("/api/customers", customer)
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
},
update: function(customer) {
var deferred = $q.defer();
$http.put("/api/customers/{id}" + customer.id, customer)
.success(deferred.resolve)
.error(deferred.reject);
return deferred.promise;
}
};
};
customerEditCtrl.js
function customerEditCtr($stateParams, $location, customerPersistenceService) {
var vm = this;
vm.editableCustomer = {};
vm.selectedCustomerId = $stateParams.id;
customerPersistenceService.getById(vm.selectedCustomerId).then(
function (customer) {
vm.editableCustomer = customer;
});
};
vm.saveCommand = function () {
if (saveCustomer) {
var customer = vm.editableCustomer;
customer.id = vm.selectedCustomerId;
if (customer.id !== 0) {
customerPersistenceService.update(customer).then(
function (result) {
return result.data;
});
} else {
customerPersistenceService.save(customer).then(
function (result) {
return result.data;
});
}
}
};
};
In the CustomerAPIController.cs my methods look like these:
[HttpPost]
public HttpResponseMessage Post([FromBody]Customer newCustomer)
{
try
{
if (ModelState.IsValid)
{
_customerService.AddNewCustomer(newCustomer);
return Request.CreateResponse(HttpStatusCode.Created, newCustomer);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
[HttpPut]
public HttpResponseMessage Put(int id, [FromBody]Customer editableCustomer)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (id != editableCustomer.Id)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
try
{
_customerService.UpdateCustomer(editableCustomer);
return Request.CreateResponse(HttpStatusCode.OK, "{success:'true', verb:'PUT'}");
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
}
Update:
After some investigation, I realise the vm.editableCustomer seems to contain an array of all customer objects making it hard to pass to the Web API POST.
I fail to understand how this object gets assigned with all customer objects.
There is a clear error:
$http.put("/api/customers/{id}" + customer.id, customer)
This will try to PUT to an url like this:
http://yoursite/api/customers/{id}927
You need to remove the {id} part, so that your url is correct:
http://yoursite/api/customers/927
The segment enclosed in braces only exists in the server side route template, and it's used to extract the parameter from the incoming URI.

How can I use node async to fetch my mongoose calls?

I'm building a site with node/express/mongoose and it needs to do the following things when viewing a submission.
The problem I'm running into is doing db fetches in a non-serial fashion. For example, I'll do a few calls to fetch some data, but some of the calls might not finish until the execution context goes to the other. Tried to use the npm module, async, but am having trouble trying to figure out how I would integrate it.
Here is my code:
var getViewCount = function(submissionId) {
Submission.getSubmissionViewCount({
submissionId : submissionId
}, function(err, count) {
if (err) {
throw err;
}
if (count) {
return count;
}
});
};
var getVotes = function(submissionId) {
console.log('getvotes');
Submission.getSubmissionVotes({
submissionId : submissionId
}, function(err, votes) {
return votes;
});
};
var getSubmission = function(id) {
Submission.getSubmission({
id : id
}, function(err, submission) {
if (err) {
throw err;
}
if (submission) {
return submission;
}
});
};
var renderSubmission = function(title, submission, views) {
res.render('submission', {
title: submission.title + ' -',
submission: submission,
views: views.length
});
};
How do I use this with async? Or should I be using async.series isntead of async.async?
async.series([
function(callback) {
var submission = getSubmission(id);
callback(null, submission);
},
function(callback) {
// getViewCount(submissionId);
},
function(callback) {
// getVotes(submissionId);
},
function(callback) {
//renderSubmission(title, submission, views);
}
], function(err, results) {
console.log(results);
});
Basically I want to fetch the views and votes first and then render my submission.
TheBrain's description of the overall structural changes that you should make to your code is accurate. The basic methodology in Node is to nest a series of callbacks; very rarely should you require functions that actually return a value. Instead, you define a function that takes a callback as parameter and pass the result into that callback. Please review the code below for clarification (where cb is a callback function):
var getViewCount = function(submissionId, cb) {
Submission.getSubmissionViewCount({
submissionId : submissionId
}, function(err, count) {
if (err) {
throw err;
}
if (cb) {
cb(count);
}
});
};
var getVotes = function(submissionId, cb) {
console.log('getvotes');
Submission.getSubmissionVotes({
submissionId : submissionId
}, function(err, votes) {
if (cb) {
cb(votes);
}
});
};
var getSubmission = function(id, cb) {
Submission.getSubmission({
id : id
}, function(err, submission) {
if (err) {
throw err;
}
if (cb) {
cb(submission);
}
});
};
var renderSubmission = function(submissionId) {
getSubmission(submissionId, function (submission) {
if (!submission) {
// unable to find submission
// add proper error handling here
} else {
getViewCount(submissionId, function (viewCount) {
res.render('submission', {
title: submission.title + ' -',
submission: submission,
views: viewCount
});
});
}
};
};

Access object properties from prototype

I have a class that wraps a mongodb client for node.js. The the class below when I call findUsers I get that this.collection is undefined.
How do I access this.collection from the prototype?
Thank you!
Class:
var Users;
Users = (function () {
function Users(db) {
db.collection('users', function (err, collection) {
this.collection = collection;
});
}
Users.prototype.findUsers = function (callback) {
this.collection.find({}, function (err, results) {
});
}
return Users;
})();
Usage:
//db holds the db object already created
var user = new Users(db);
user.findUsers();
You are doing it right in the prototype method, your error is in the callback function of db.collection().
var Users = (function () {
function Users(db) {
var that = this; // create a reference to "this" object
db.collection('users', function (err, collection) {
that.collection = collection; // and use that
});
}
Users.prototype.findUsers = function (callback) {
this.collection.find({}, function (err, results) {
});
}
return Users;
})();
Use another reference:
Users = (function(){
var that = this;
function users(db)
{
db.collection('users', function(err, collection)
{
that.collection = collection;
}
}
})();

Categories