Second sinon stub not called in async parallel - node.js

I am trying to test the following code:
var archive = function(callback){
call to this.archive() here...
}
var map = function(callback){
call to this.map() here...
}
async.parallel([map, archive], function(error){
handle errors here...
})
I am testing that the handle errors functionality is working by stubbing the archive and map functions so that one of them returns an error:
var mapStub = sinon.stub(MyClass.prototype, 'map').yields("mock error",null );
var archiveStub = sinon.stub(MyClass.prototype, 'archive').yields(null,null );
The problem I am having is that the archiveStub does not seem to be being used, as I am getting errors from a function which is called by that function (which would be expected if that function was called as I have not initialised variables for this test).
I have another test, where the archive function returns an error instead of the map function, and this test passes without seeming to call either of the stubbed methods instead of the stubs.
var mapStub = sinon.stub(MyClass.prototype, 'map').yields(null,null );
var archiveStub = sinon.stub(MyClass.prototype, 'archive').yields("mock error",null );

You want to use yieldsAsync instead of yields, otherwise the error is yielded prematurely (before all the parallel "tasks" have been started) and async.map() stops any further processing (using yields basically turns it into a synchronous operation).

Related

Nodejs Callback: How to define a Callback?

I am reviewing a sample nodejs server code, which is working fine. but could not understand the following code:
var handlers = {};
// Creating a sample handler
handlers.sample = function(data,callback){
callback(406,{'name':'sample handler'}); // How is this line of code working??
};
// Creating a not found handler
handlers.notFound = function(data,callback){
callback(404); // How is this line of code working??
};
In the entire code there is no implementation of "callback" function then how
callback(406,{'name':'sample handler'});
and
callback(404);
are working?
Please suggest. Thanks.
callback isn't implemented in the code you posted; it's a named parameter.
To call one of the functions that requires a callback, you'll need to pass it in as an argument, like:
handlers.sample("some data", () => console.log("I'm in a callback!));
The first argument ("some data") goes in the data parameter, and the second argument (() => console.log("I'm in a callback!)) goes in the callback parameter. When callback(404) is run, it executes the callback function (in the above example, it would do console.log("I'm in a callback!)).
Basically, when you call handlers.sample, you should pass a function as your second argument, and that function will be called, usually asynchronously, and presumably after something is done with the data you pass as the first argument. For example, based on the code you provided:
handlers.sample(dataObject, (number, object) => {
console.log(number)
console.log(object.name)
})
would yield this result in the console:
406
sample handler
I’m curious if this is a public library you are seeing this code in, so we can take a closer look?
I did a further digging in into this and found that
selectedHandler
in the following code (this is not mentioned in the question) is getting resolved into handlers.sample or handlers.notFound variable names based on some logic (which is not mentioned here)
selectedHandler(data,function(status,payloadData){
// somelogic with the status and payloadData
});
And second parameter of this function which is a complete function in itself
function(status,payloadData){
// somelogic with the status and payloadData
}
is going as the second parameter in handlers.sample or handlers.notFound which is a Callback. So execution of Callback in the current context is execution of this function (this function is anonymous because it has no name and getting executed as Callback)

How can i access variable inside callback nodejs?

I'm unable to get the values in meals object although i have create new object at the top can any one tell which is the best procedure access variable inside callback function
var meals = new Object();
passObj.data = _.map(passObj.data, (x)=> {
x.mealImageUrl = !_.isNull(x.image_url) ? `${config.image_path}${x.image_url}` : x.image;
dbHelpder.query(`select * from meals where meal_category = ${x.category_id}`,(error,result)=>{
meals = x.result;
passObj.total = 555
});
return x;
});
You need to use callback again inside the callback function. :)
You are doing something asynchronous, it means, there are no sequence codes. (At least, I keep this in my mind, don't know how others think about this.) So, the code should be:
function somehow(callback) { // you get the result from callback
var meals = new Object();
passObj.data = _.map(passObj.data, (x)=> {
dbHelpder.query(`select * from meals where meal_category = ${x.category_id}`,(error,result)=>{
meals = x.result;
passObj.total = 555;
callback(meals); // Here you get the result
});
}
return x;
}
So, when you are going to use this function, it should be
function afterMeals(resultMeals) {
// do something on the meals
}
somehow(afterMeals);
Use some other technology can make it a bit clear (like promise), but you can not avoid callback actually.
First of all, I cannot see what passObj exactly is, apparently it is defined elsewhere.
Secondly, callback functions don't function the way you seem to think they do. Typically one reason to use them is to implement asynchronous calls, so returning a value is not of use.
The idea is as follows. Usually you have a call like this:
var myFunc1 = function(){
return 42;
}
var x = myFunc1();
myFunc2(x);
However when myFunc1 is an asynchronous call returning a value is impossible without using some sort of promise, which is a topic on its own. So if myFunc1 was an asynchronous call and the 42 was returned e.g. by a server, then just returning a value caused the value to be null, because the return value is not calculated and received yet, when you arrive at return.
This is a reason for callbacks to be introduced. They work in a way, that allows for asynchronous calls and proceeding the way you want to after the call has finished. To show on the example above:
var myFunc1 = function( myFunc2, params ){
// do async stuff here, then call the callback function from myFunc1
...
myFunc2(x);
}
So the asynchronous function doesn't return anything. It makes the calls or calculations it needs to make and when those are done (in the example that is when x has been declared and assigned a value) myFunc2, which is the callback function in our example, is called directly from the asynchronous function.
Long story short - do what you need to do with x directly inside the callback function.

How to synchronously call multiple functions which contain mongoose queries in nodejs?

I want to execute 4 functions in order. Each functions is of the below format. Like create update delete and display. I want to call the display function after completing the other 3 functions. I tried promise method but without any db call it is working in order.When a mongoose call is happening, the order is getting changed.
function createProjects(req) {
var projects = req.body.created;
projects.forEach(function (project) {
var newProject = new ProjectSchema(project);
newProject.save(function (error, object) {
if (error) {
console.log(error)
}
console.log(object)
});
});
}
How this issue can be resolved?
You need the code to wait until one promise completes before starting the next one, using something like bluebird.each, the async library, or a next callback queue. The first part of that sentence may sound like a duh sort of thing, but in node.js .save will always return immediately, regardless of when the callback is executed (making it less obvious in the code).
Here's an example with bluebird.each I tried to stick to the code style you are using in your example code.
var Promise = require('bluebird');
function createProjects(req) {
var projects = req.body.created;
return Promise.each(projects, function (project) {
return new ProjectSchema(project).save();
});
}

nodejs call two class functions synchronous

I have two class functions in nodejs and I want to call both synchronously both one after another.
var questionData = questionModelObj.getQuestionbyId(req.params.id);
var answerData = answerModelObj.getAnsByQuesId(req.params.id);
Here questionModelObj take time to execute and it calls answerModelObj without completing questionModelObj. It results answerData overwrites the questionData.
Please suggest how to call these two functions one after another(synchronous) and explain.
One option is to execute the second function as a callback to the first. This is pretty standard for Javascript.
// Declare variable to hold response
var answerData;
var questionData = questionModelObj.getQuestionbyId(req.params.id, function() {
// This is the callback function
answerData = answerModelObj.getAnsByQuesId(req.params.id);
}
The function signature of getQuestionbyId would then need to take in 2 parameters, the second being a function to be called later on:
questionModelObj.getQuestionbyId = function(id, callback) {
// Do things with the id
callback();
}
The callback function is then called after getQuestionbyId is done.

What is the scope for a function's arguments when dealing with inner asynchronous calls?

In my following example the arguments of one of the express app callbacks are behaving differently depending on if they are encapsulated inside an auxiliary function or not. I have solved my problem but I would like to understand better what is happening here.
getItem and buildView return promises created with Q.
The following code works (i. e. no fail callback is ever called):
var app = require("express")();
app.get('/item/:itemId', function(req, res){
var showItem= function(item){
var s = function(x){res.send(x);};
buildView(item).then(s).fail(console.log);
};
var showError = function(error){
res.send(error.message);
};
getItem(req.params.exception_id)
.then(showItem).fail(showError);
});
And the following code doesn't (console.log prints [TypeError: Cannot read property 'req' of undefined]):
var app = require("express")();
app.get('/item/:itemId', function(req, res){
var showItem= function(item){
buildView(item).then(res.send).fail(console.log);
};
var showError = function(error){
res.send(error.message);
};
getItem(req.params.exception_id)
.then(showItem).fail(showError);
});
(The difference is in the fourth and fifth lines, the fourth is deleted and the fifth is modified).
It is clear that the promise buildView is being resolved successfully, otherwise the first approach would fail as well; and until the point where buildView is applied both implementations have followed exactly the same steps.
Why are not these implementations getting exactly the same?
Shouldn't it be that when the promise buildView is resolved .then(res.send) should execute res.send with the resolved value of the promise as its argument? (i. e. the first implementation).
The following will work:
buildView(item).then(res.send.bind(res)).fail(console.log);
When you simply do then(res.send), this context of res is lost: send function is detached from res object context.
It has nothing to do with asynchronicity as this is a known feature of this in JavaScript.

Resources