client.on('message', function(obj){});
This works fine, but I am trying to avoid nesting, so I take the callback function out like so:
client.on('message', doThis(obj));
function doThis(obj) {}
But this gives me an error saying obj is undefined.
How do I pass the message data to the callback function?
Thanks
client.on('message', doThis);
function doThis(obj) {}
f(doThis) is the correct syntax. f(doThis(arg)) is the wrong syntax.
The latter is calling doThis immediately with the argument arg (which doesn't exist yet).
That's why it says obj is undefined because your calling doThis immediatly.
What f(doThis) does is passes the function on instead of the return value of the function
Related
I'm new to flowjs and do not yet understand how the typical use case of an undefined parameter should be modeled in flowjs.
function msg(message: string, callback: ?Function) {
// ...
if (_.isFunction(callback)) {
callback();
}
}
When checking the above function with flow, the following error message is shown:
Function cannot be called on possibly null value function call.
Function cannot be called on possibly undefined value
I do understand why the errors are shown but I'm not sure how to tell flowjs that this is intentional because the callback is only invoked when the parameter is not null or undefined?
Flow does not know that _.isFunction(callback) returns true only if callback is a function. All it knows is that it returns a boolean (if you have the interface file for underscore/lodash set up). You should do native JS checks instead, then Flow can refine the type of callback from ?Function to Function. Like this: if (typeof callback === 'function') { callback() }.
A simpler type check should work as well: if (callback) { callback() } because Flow knows that if callback is not falsey, it has to be a function.
See more at https://flowtype.org/docs/dynamic-type-tests.html
I got the following code:
navigator.geolocation.getCurrentPosition(
successFunction
);
I was wondering why it is not required to use the '()' at the end of the succesFunction? Isn't it required to call a function with the '()' --> somefunction()
What's the logic behind it?
Because you're passing in the function reference, not the returned value of the function.
A function is a thing that can be invoked—where it runs code and returns a result. You invoke a function by using the parentheses. But, if you want to talk about the thing, if you want to pass the function around so that someone else can invoke it, you leave off the parentheses.
In this case, the getCurrentPosition() function is asking you to give it a function so that it can call it later on. So instead of invoking successFunction, you pass along a reference to it.
If you instead wrote:
navigator.geolocation.getCurrentPosition(
successFunction()
);
…then what would happen is successFunction() would be invoked—the code of the function would be run, and possibly return a value—and THEN you would invoke getCurrentPosition(), passing along as an argument whatever value successFunction returned.
In JavaScript you can pass functions as objects:
Try executing this example:
function myFunction() {
console.log('hello');
}
function anotherFunction(functionParameter) {
console.log('executing function passed as argument:');
functionParameter();
}
anotherFunction(myFunction);
This code will print:
"executing function passed as argument:"
"hello"
How does the callback in fs.readfile get called when using fs.readfile.bind(context,pathArgument) like so. //understandable because my task function knows the name of the callback parameter
async.series([function(callback){
//operation done callback()},...],finalCallback(err,result));
BUT
//not understandable
async.series([fs.someOperation.bind(null,firstArgument),...],finalCallback(err,esult))
I believe I understand partial application;however, it would look something like this. function(callback){ fs.someOperation(firstArgument, ????)}(asyncCallbackFunc) and then I have no idea how the second argument is called...
Thx, in advance for helping me clear this up.
All bind does is set the context of the callback. It is still a regular callback like any other. Except, it is explicitly told what this will be. Looks like in your case, it is set to null.
The bind function on function object allows you to set the context i.e the value of this inside the function body as well as allow you to create a partial function in case you pass some arguments while calling bind.
For example:
function add(a,b) {
console.log(this);
return a+b;
}
var newAdd = add.bind("hello world", 10);
The newAdd will be one argument function which gets added to 10 and the result is returned. Also when newAdd is called the "hello world" will be logged in console.
Now when your code says fs.readFile.bind(null, path) it means that the return function will be of one argument which is the callback for readfile i.e the return function will be of form function(callback) { ... } which is exactly what is required to be passed to async.series
The main idea in the code you posted is to create a partial function that accepts only callback so that it can be passed to async.series the null argument doesn't play any role but you need to pass a context argument to call bind function, hence a null is passed as context arg.
So, I've figured out how to call a method in JavaScript when you have the method name in a string e.g. strCallback = 'targetMethod'; window[strCallback]();, however, I get the following error message indicating that it can't find the method and after researching I'm still not sure why.
Calling the method by the actual name works, but not by using window[strCallback]();
Error:
Uncaught TypeError: Object [object global] has no method 'targetMethod'
Code:
function startMethod(strCallback) {
var results = '...';
// window[strCallback](results); // <-- Causes error
targetMethod(results); // <-- Works
}
function targetMethod(r) {
console.debug(r);
}
startMethod('targetMethod');
Thanks for any help.
From the discussion in comments it looks like the problem is the context in which the callback method is declared. If you use window[callback] it expects the callback to me declared in the global context, in your case it does not appear to be the case. It might be because you have declared everything inside a anonymous function/dom ready creating a closure context for the function.
As a solution I would recommend not to pass the callback as a function name string, instead pass it as a function reference.
So instead of calling startMethod('targetMethod');, you need to call startMethod(targetMethod); and invoke callback using strCallback() instead of window[strCallback](results);.
I solution we worked out in the comments was just a workaround where we forced the callback to the global scope which is not a recommended method
I am trying to understand a code from socket.io/examples/chat/app.js.
I am not able to explain what the fn() calls mean in the lines 71 and 73.
I guess it is a callback function but where is its definition?
Is it a short invocation of another function from app.js ?...
Is it a call of a prototype function of the socket object?
The fragment is (lines 69-78):
[...]
socket.on('nickname', function (nick, fn) {
if (nicknames[nick]) {
fn(true);
} else {
fn(false);
nicknames[nick] = socket.nickname = nick;
socket.broadcast.emit('announcement', nick + ' connected');
io.sockets.emit('nicknames', nicknames);
}
});
[...]
fn is passed in as an argument to the callback function, right here:
socket.on('nickname', function (nick, fn) {
^^
Since JavaScript functions are objects, they can stored in variables — and passed as arguments into other functions.
The use of the callback function in this particular case is duscussed in the “Getting acknowledgements” section of the Socket.IO docs — calling it with some data sends a message back to the client as a response to that message.
fn is a reference to another function that is being called from within the on nickname event.
IN javascript, functions are treated as objects so they can pass as an argument with in a callback function.