How can I call a custom function using a library? - node.js

I am trying to call a custom function based on this documentation:
.addFunctionEmoji(":regional_indicator_v:", deleteUser())
...
Function deleteUser() {
console.log(“works”)
}
I get the following error message:
Failed to send message
TypeError: Callback for :regional_indicator_v: must be a function type.
How can I call my function here?

addFunctionEmoji expects a function as the second parameter.
In order to invoke deleteUser, the best thing is to wrap it in a function:
.addFunctionEmoji(":regional_indicator_v:",() => deleteUser())

Related

Pass extra argument into callback

Say I have a function with a callback:
client.on("foo", (arg1, arg2, arg3) => {
// ...
client.bar();
} );
Now I want to seperate the callback into a different module:
const eventHandler = require('./eventHandler.js');
client.on("foo", eventHandler.foo);
I now need access to the clientvariable in the eventHandler.js module, because I need to call client.bar();. How would I go about passing client into the eventHandler.foo function?
You can create an inline callback and call the event handler with any arguments you want.
Example:
client.on("foo", () => eventHandler.foo(client));
However, looking at your code, it appears that the on event is a property on the client itself. Can't you just edit the code of client and make it pass itself as an argument to the callback function?

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)

DocumentDB readCollection function error

I'm trying to use the "readCollection" function, but I get an Error:
The "options" parameter must be of type "object". Actual type is:
"function".
my code:
docDbClient.readCollection(docUrl, function (err, collection) {
console.log(collection);
}, function(err){
console.log(err);
});
The docUrl var is equal to my document._self path.
This code was working before, but for some reason it not anymore without me making any changes.
From what the error says the 'option' parameter needs to be an object instead of a function, but from what I read on the documentation the 'option' parameter is optional which I don't have it with in my function.
I'm also getting the same error when I use the replaceDocument function.
http://azure.github.io/azure-documentdb-node/DocumentClient.html#readCollection
The problem is that you have an error handling function in your parameter list, which causes it to think that the second parameter is options. Remove the error handling function, and add code inside your main handler to process it if err does not come back null.

Understanding Callbacks

I am very confused when it comes to javascript callbacks... Especially when attempting to learn node at the same time.
You see, I understand the concept of passing a function as a parameter to another function but what confuses me mostly are the premade modules that "accept" callbacks functions.
For example a simple request looks like so:
var request = require('request');
var url = 'http://www.google.com';
request.get(url, function(error, response, body) {
if(error){
console.log('This request resulted in an error', error);
}
console.log(body);
});
This get method accepts a url and a callback.
Who defines that a callback is accepted? The developer of the specific method?
Also, the 3 parameters that we pass within the function (error, response, and body)... how does the request module know to populate these variables with data on return?
Imagine get implemented more or less like
function get(url, callback) {
var response = they somehow retrieve the response;
var body = they somehow parse the body;
var error = ...;
// they call you back using your callback
callback( error, response, body );
}
How these values are computed is irrelevant (this is their actual job) but then they just call you back assuming your function actually accepts three arguments in given order (if not you just get a runtime error).
In this sense they also kind of "accept" your callback by ... well, calling it back :) There is no worry about the number of arguments as Javascript is very "forgiving" - methods can be called with any number of arguments, including less or more arguments than the function expects.
Take this as an example:
// they provide 3 arguments
function get( callback ) {
callback( 0, 1, 2 );
}
// but you seem to expect none
get( function() {
});
The get assumes that the callback accepts three arguments while I pass a method that supposedly doesn't accept less arguments. This works, although the three arguments, 0, 1 and 2 are not bound to any formal callback arguments (you can't directly refer to them), they are there in the arguments object, an array-like structure:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Take another example
function get( callback ) {
callback( 0, 1, 2 );
}
get( function(a,b,c,d,e) {
});
This time the callback I pass seems to expect more arguments than the caller provides and still, no problem here. Arguments are bound to consecutive call parameters, a will get 0, b will get 1, c will get 2 and d and e will get undefined inside the callback body.
Both examples show that the caller doesn't really care how your callback is defined, whether its number of arguments matches the expectation or not. In case of any mismatch, the worst what could happen is a runtime error:
function get( callback ) {
callback( 0, 1, 2 );
}
get( 1 );
// Uncaught TypeError: callback is not a function
The designer of a function/method decides what arguments it will accept and process. So, if a function accepts a callback as an argument, then it is the design and implementation of the function that decided that and will call the callback at the appropriate time.
It is also the implementer of the function/method that decides what arguments will be passed to the callback when it is called. What confuses many people is that is is the caller of the function that defines the callback function itself that will be called by the main function/method. But the arguments of the callback function MUST be declared to match what the main function/method will pass to the callback. The labels given to the arguments when you define the callback are merely labels for programming convenience (as a means of referring to the arguments by name). How the callback's arguments are defined in the callback function has nothing to do with what is actually passed to the callback - that is all decided by the function/method that calls the callback. So, when you use request.get(), the contract for using it is that it accepts a callback that should be declared to have the arguments (error, response, body) because that's what it will be called with. Now, it is OK to leave off arguments at the end if you aren't going to use them (they will still be there, but you just won't have a convenient name to refer to them by), but you can't leave off arguments before any that you intend to use because order is important.
Who defines that a callback is accepted? The developer of the specific
method?
Yes, the developer of the function/method decides if a callback is accepted.
Also, the 3 parameters that we pass within the function (error,
response, and body)... how does the request module know to populate
these variables with data on return?
The request.get() method is programmed to pass three arguments (error, response, body) to its callback and that's what it will pass. No matter how the callback itself is actually declared, request.get() will pass these three arguments in that order. So, what confuses many people is that the caller of the function/method creates the callback function itself and gets to define the arguments for it. Well, not really. The creator of the callback must create a callback that matches the contract the the function/method is expecting. If it doesn't match the contract, then the callback likely won't function properly as it will get confused about what it was passed. Really the contract here is that the first argument to the callback will be an error value and if that value is not truthy, then the next two arguments will be response and body. Your callback must match that contact in order to use those arguments correctly. Because Javascript is not strictly typed, it will not be a run-time error if you declare your callback incorrectly, but your access to those arguments will likely be wrong - causing things to work incorrectly.
For example, if you declared your callback to be:
function myCallback(response, body, err) { .... }
Then, what your callback sees as response would actually be the error value because request.get() put the error value in the first argument, no matter how the callback itself is declared.
Another ways of seeing this is to define a callback with no defined parameters and then access them entirely with the arguments object.
function myCallback() {
console.log(arguments[0]); // err value
console.log(arguments[1]); // response value
console.log(arguments[2]); // body value
}
The same is true of the return value in the callback. If you are using Array.prototye.map(), it expects a callback that is passed three arguments and returns a new array element. Even though you are implementing the callback, you must define a callback that is compatible with that contract.
This get method accepts a url and a callback. Who defines that a callback is accepted? The developer of the specific method?
Yes. The author(s) of request.get() defined it specifically to expect and make use a "callback" function.
You can define your own functions to accept callbacks as well, especially useful when they depend on other asynchronous functions – such as setTimeout() for a simple example.
function delay(value, callback) {
setTimeout(function () {
// this statement defines the arguments given to the callback
// it specifies that only one is given, which is the `value`
callback(value);
}, 1000);
}
delay('foo', function (value) { // named to match the argument `delay` provides
console.log(value);
});
Also, the 3 parameters that we pass within the function (error, response, and body)... how does the request module know to populate these variables with data on return?
The arguments given and their order are part of request's definition, same as delay() above defining that (value) would be the argument(s) for its callback.
When providing a callback, the parameters only give the arguments names for you own use. They have no effect on how the main function (request.get(), delay(), etc.) behaves.
Even without naming any parameters, request.get() is still passing the same 3 arguments in the same order to the callback:
request.get(url, function () { // no named parameters
var error = arguments[0]; // still the 1st argument at `0` index
var body = arguments[2]; // still the 3rd argument at `2` index
if(error){
console.log('This request resulted in an error', error);
}
console.log(body);
});

Wrapping an async function and maintain async

I am using the node request module which is setup as follows:
request(object,function(data));
The function is a callback with the response data in it. I want to feed in a predefined set of objects, and wrap the request function in another function like so:
var quickReq(object,func){
request(object,func);
}
quickReq({
"method":"GET",
"url":"http://someapi.com",
}
,function(error, response, data) {
res.send(data);
});
Is this valid async code?
Is this valid async code?
Yes, yes it is.
It's not at all clear what you're trying to do, but the first parameter to request's callback is an error code, and the second parameter is the returned content (assuming it succeeded).

Resources