0

I am writing a ping application that logs every ping to a log file. Depending on the result I write an info or a error entry.

Here is the ping function:

function pingServer(item){
    var monitor = new Monitor({
        website: item.url,
        interval: interval
    });
    monitor.on('up', writeInfo);
    monitor.on('down', writeError);
}

I would like to have a unique callback function writeLog instead of writeInfo and writeError functions, but I dont know how to pass an argument in that callback.

So instead of

function writeInfo(res){
    logger.info(getVarLine(res));
}


function writeError(res){
    logger.error(getVarLine(res));
}

I would have something like:

function writeLog(res, level){
    if (level=='info'){
        logger.info(getVarLine(res));
    } else {
        logger.error(getVarLine(res));
    }
}
2
  • What you want to do looks fine. What problem are you experiencing? Commented Mar 17, 2016 at 19:23
  • I don't know how to pass level as a param in the callback Commented Mar 17, 2016 at 19:24

2 Answers 2

3

Here are three options:

  1. Use .bind() to automatically prepend arguments to the callback (technically this creates a new function stub that adds that argument).
  2. Manually create your own wrapper function that adds the argument.
  3. Create a new version of .on() that accepts your level argument and adds it to the callback before calling the callback.

Using .bind()

If you are not relying on a value of this being passed into your callback, then you can use .bind() to create a new function that will have the level argument automatically prepended to the callback arguments.

// note how the arguments had to be switched here so level was first to match
// up with how .bind() works
function writeLog(level, res){
    if (level=='info'){
        logger.info(getVarLine(res));
    } else {
        logger.error(getVarLine(res));
    }
}

function pingServer(item){
    var monitor = new Monitor({
        website: item.url,
        interval: interval
    });
    monitor.on('up', writeLog.bind(null, level));
    monitor.on('down', writeLog.bind(null, level));
}

Manually Creating Your Own Wrapper Function

Or, you can create your own wrapper function that returns a function, but captures the parameter you wanted:

function writeLogCallback(level) {
    return function(res) {
        if (level=='info'){
            logger.info(getVarLine(res));
        } else {
            logger.error(getVarLine(res));
        }
    }
}

function pingServer(item){
    var monitor = new Monitor({
        website: item.url,
        interval: interval
    });
    monitor.on('up', writeLogCallback(level));
    monitor.on('down', writeLogCallback(level));
}

Creating a Replacement for .on()

Or, you can create a wrapper for monitor.on() that captures your level value:

Monitor.prototype.onWithLevel = function(event, level, callback) {
    this.on(event, function(res) {
        return callback(res, level);
    });
}

function writeLog(res, level){
    if (level=='info'){
        logger.info(getVarLine(res));
    } else {
        logger.error(getVarLine(res));
    }
}

function pingServer(item){
    var monitor = new Monitor({
        website: item.url,
        interval: interval
    });
    monitor.onWithLevel('up', level, writeLog);
    monitor.onWithLevel('down', level, writeLog);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Just one question, when you say "If you are not relying on a value of this" what do you mean?
@ERodriguez - .bind() requires you to pass it, in advance, the value of this that will be set for the callback function. If you aren't using this in your handler, then that will not matter. If you are, then you will have to either make sure you pass the right value for this or you will have to use one of the other techniques. If you don't know what this is or how it's set, then see this answer: stackoverflow.com/questions/28016664/…
0

Here's how you could achieve what you want (ie pass an argument to a callback):

monitor.on('up', writeLog('info'));
monitor.on('down', writeLog('error'));

// You pass the log level
function writeLog(level) {
    // and you return a function that will be called
    // with your data when the event is triggered
    return function(res) {
        if (level=='info'){
            logger.info(getVarLine(res));
        } else {
            logger.error(getVarLine(res));
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.