How to call callback function in within callback function in node.js
callbacks are simply parameters in JS, just like others
just pass it to other functions
also notice that JS is lexical scoping
so make sure ur callback parameter in the scope or outer scope
--> What is lexical scope?
Call back functions in node js are no different than those in javascript. This is one way you can call it.
function someFunction(callback){
callback(params);
}
the call back function can be defined as any normal function.For example
function random(number){
return Math.random()};
the function someFunction can now be called as
someFunction(random);
That's it.The important thing to understand here is that node js is still javascript.So everything trick that works in javascript will work in node js.
Related
I am trying to use authentication with socket.io's io.use() as they've mentioned in their documentation. They seem to have an example of io.use() in which the function calls next(), but I am getting the error:
TypeError: next is not a function
for using using io.use(passport.authenticate('google'))
Update
I know that the documentation shows that I need to pass next as an argument. But I cannot pass next, because the passport.authenticate() method is defined by passport.js, I am not declaring it there (like in the docs).
The only option I think I can use is defining a function and using passport.authenticate inside it. But I am not sure if that would be the correct way to go. I may also need to handle custom callback if I do so.
You need to pass next as an argument
I am going through some code on github: https://github.com/linnovate/mean/blob/master/server/routes/user.route.js
But there is a portion of it I don't understand, that is:
router.route('/')
.post(asyncHandler(insert));
On npm express-async-handler
is described as:
Simple middleware for handling exceptions inside of async express routes and passing them to your express error handlers.
They go give an example of how to use the module, but it doesn't explain much.
So my questions are:
How is the insert function on line 12 called without parentheses?
What is the function of asyncHandler(), what would the code look like if you decide on not using it?
Normally when using router.route('/').post there are curly braceswhich follow. In this code I cant see any. So my question are: Is the async function insert part of the function body of router.route('/').post? and if not then why are there no curly braces?
What exactly is being exported here user.controller.js on line 14 (is it an object, a var...)? What is the advantage of exporting it this way? Why not just export the function insert()?
Thank you in advance.
How is the insert function on line 12 called without parentheses?
The insert function is not called here. It is passed to asyncHandler() as a function reference so it can be called later. It is asyncHandler() which is called immediately and that returns a new function that is passed to .post() as the request handler.
What is the function of asyncHandler(), what would the code look like if you decide on not using it?
This is a wrapper around insert that looks for a rejected promise returned from the function and, if found, calls next(err) automatically.
Normally when using router.route('/').post there are curly braceswhich follow. In this code I cant see any. So my question are: Is the async function insert part of the function body of router.route('/').post? and if not then why are there no curly braces?
I'm not sure what you mean by curly braces. .post() expects a function reference to be passed to it that will be called with a certain set of parameters when the defined route matches an incoming request. It can use as either of these:
// externally defined request handler function
router.route('/').post(someRequestHandlerFunc);
// inline defined request handler function
router.route('/').post(function(req, res, next) {
// code here for the request handler
});
What exactly is being exported here user.controller.js on line 14 (is it an object, a var...)? What is the advantage of exporting it this way? Why not just export the function insert()?
I'm assuming the line 14, you're asking about is here. That's just exporting the insert function on the insert property of this modules exports. When you export a function, you don't use insert(). That calls the function immediately. You just refer to the function's name as insert to export a reference to the function that can be called later.
The reason to export is as a property of an object rather than just export the single function is to make the module extensible so it can export other things as different named properties.
I'm just trying to get a grasp of what middleware refers too. At first I thought it was functions used in the framework express. Although now I'm getting a sense that they simply just refer to functions that get in the middle between asynchronous functions.
I know it's common to see next() get used to move from one middleware to the next. Both express and mongoose have the next() call with similar names. I'm concerned as I don't see mongoose or express refer to each other in their documentation. So this leaves me to believe the context of their middleware is just for themselves.
http://mongoosejs.com/docs/middleware.html
http://expressjs.com/en/resources/middleware.html
When combining express with mongoose are all the middlewares lined up together/concatenated or is it separate?
e.g. together/concatenated
- calling next() on mongoose will also trigger expresses middleware function
e.g. Separate
- mongoose just has it's middleware next() just move for pre/post hooks
- express also just has it's middleware next() just move towards it's supported middleware functions
Short answer: they're separate.
Longer answer: By convention, most middleware stacks implement some kind of next function to call in order to proceed down the stack and call each middleware function in turn.
It's a matter of scope. Express and Mongoose both have their own independent middleware stacks, so what the next function does depends on where it gets called. As a general rule of thumb, every function-- including the anonymous functions used for callbacks that accept a next parameter-- have their own scope.
Consider the following really brief example of differently scoped, but otherwise identical parameter names:
function doSomething(arg) {
console.log(arg)
function doSomethingElse(arg) {
console.log(arg);
}
doSomethingElse('different');
}
doSomething('original');
// Outputs
// > 'original'
// > 'different
Even though doSomething and doSomethingElse both have a parameter called arg, the value logged to the console by doSomethingElse is the value actually passed to that function-- the value of arg as scoped to the function it was called in, not the scope surrounding it.
This is true for Mongoose middleware applied within Express middleware (or vice-versa): they just happen to share a similar, conventional parameter name.
As a learning experiment, you should deviate from conventions for a moment (but not forever; conventions exist for a reason!) to name your Express and your Mongoose next parameters something else in a single file-- expressNext and mongooseNext, perhaps-- to help differentiate them in your mind.
I am trying to create a Node module (using harmony) that upon loading by another module/application, has to be yielded to so that things in it's construct can be executed and loaded before any of it's exposed functions can be called.
The issue I am having is that I cannot seem to yield to the internal function that is being executed, using module.exports. An example would help.
module.exports = function*(s_id){
console.log('loading the module lets it execute up till here');
if (!(this instanceof Tester)) return yield new Tester();
}
function* Tester(){
console.log('but we never execute this generator function');
}
Tester.prototype = {
model : function*(){
// other functions
}
}
It's been stumping me for hours now! I feel like the solution is super simple but I cannot seem to wrap my head around it. I have tried to simply make the Tester() function the export, but am still having the same issue. Why can't I seem to yield to the Tester() function?
Also, what may an alternative be to this approach? I want to maintain the Object nature of the module so that the module can be loaded with different inputs, such as the s_id variable/object in the example above.
a Node module (using harmony) that upon loading by another module/application, has to be yielded to so that things in it's construct can be executed and loaded before any of it's exposed functions can be called
Don't do that. Generators are not made for asynchrony. yield doesn't do what you want here. A module is not "yielded" to await something in it to load. yield is magic, but not async magic.
If you must use an asynchronous module loading process, export a promise for your actual module. That is a standard interface for something to await, and can be consumed using a standardized approach that does not rely on internals of your module.
You still can use yield syntax for constructing that promise, just use your favorite coroutine library.
return yield new Tester();
…
function* Tester(){…}
Uh oh. Well yes, apparently it is possible to call generator functions as constructors. But believe me, it is not what you want. A constructor for an arbitrary object should return that object, instead of an iterator (just like it shouldn't return a promise). If some of your object methods are generator methods, that's fine, but your constructor should be not.
If you really want to use a generator function in your code like that (and it's not meant to be a constructor), you
will need to yield* the iterator you've created (tester()) instead of yielding it
must not overwrite its .prototype property like you did, as that causes the iterator to malfunction. (Of course you should never do that at all, even though most of the time it works)
I have a little Greasemonkey script that communicates with a servlet on (my) server. The servlet is sending back JavaScript code, which I eval() in the onload handler of the GM_xmlhttpRequest.
So far, all is working fine. Now, I'd like to use send another GM_xmlhttpRequest from within that eval()ed code. and here I'm stuck. I do not see any error, but all GM_* functions appear not to be working from within the eval(responsetext).
If I hard code the GM_xmlhttpRequest in the onload handler (no eval()), it is working fine.
It is possible to work around this problem, you can call GM_* functions with setTimeout set to 0 from eval'ed code. Try something like:
function myFunction()
{
GMXmlHttpRequest(...)
}
eval('setTimeout(myFunction, 0)');
A better solution is to extend Function.prototype with a function called safeCall that does this for you. Whenever you have any eval'ed code that will call into GM_* functions you'll need to have safeCall somewhere in that call chain.
Greasemonkey (GM) is hosting the user script, which means that it can add functions and objects to the user script, when you call eval() the script runs unhosted (the vanilla JavaScript is running it) and you don't get the GM API inside of it.
There is another solution. I have the similar problem, I don't want to put all my logic in user script, because if I change them, user need to update them by themselves. So what I want to do is separating the main logic from loading logic, the main logic will be loaded at beginning by the user script and eval them.
So I made a function "sendRequest", which is a wrapper of GM_xmlhttpRequest(), I need it anyway, because the method, server url and onError callback are always same for my application, so I just put them into my "sendRequest" function to make the xmlhttprequest simple.
In the main logic javascript code, which is loaded from server, there is no greasemonkey function call at all. If I want to for example communicate with server, I will call sendRequest instead. It works.