Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

179
Views
Add an extra parameter to a callback function in Javascript

Hello Stackoverflow users,

Many peoples like me searched for how to pass extra arguments to a callback function. The questions have similar titles but actually they have different challenges and many ways to solve. Plus, it is always a pleasure to share practices to be more experienced.

Recently, I faced a pretty simple challenge in my node js project. One of the APIs I communicate with has an SDK that works synchronically. And I used to pass callback functions every time (which is annoying when you have requests depending on each other and some data needs to transfer within the app layers).

Imagine a plan payment flow that goes like this, a client sends a request to the server including the selected plan and his ID. When the server API layer receives the request data, it passes it to a third-party service function ( .create(...) ). The third-party service function receives a callback with 2 parameters function(err, plan_document). And then, the callback is supposed to apply the selected plan logic on the client by the ID in the request.

** We need to pass the client's and the plan's data to the callback function to apply the logic. The third-party service provides to the callback a plan_document parameter and we still need to somehow pass the client id from the API layer to the service.

The code will look like this.

const create_plan_agreement = (req, res) => {
    // some code
    var client_id = req.auth.client_id;
    third_party.plan_agreement.create({}, update_plan_agreement);
};
const update_plan_agreement = (err, plan_document, client_id) => {
    /* 
        The third-party `third_party.plan_agreement.create` function passes the first 
        two parameters and somehow we need to add the client_id 
    */
    console.log('client plan activated');
    active_client_plan(plan_document, client_id);
};

------------------ EDIT ------------------

I wonder what if the flow was longer and I need the client id farther than the update function like this.

const create_plan_agreement = (req, res) => {
    // some code
    var client_id = req.auth.client_id;
    third_party.plan_agreement.create({}, update_plan_agreement);
};
const update_plan_agreement = (err, plan_document) => {
    console.log('plan activated, send notification to the client');
    third_party.plan_agreement.update(plan_document, send_agreement_notification);
};
const send_agreement_notification = (err, plan_document) => {
    console.log('client plan activated');
    active_client_plan(plan_document, this.client_id);
};

What should I do in this case? Should I keep repeating the.bind({'client_id': client_id}) function until the last step in the flow?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

If you want to support older people, you can easily bind using a containing callback, like this:

const create_plan_agreement = (req, res) => {
  // some code
  var client_id = req.auth.client_id;
  third_party.plan_agreement.create({}, function(params, from, create) {
    update_plan_agreement(params, from, create, client_id)
  });
};

const update_plan_agreement = (err, plan_document, client_id) => {
  /* 
      The third-party `third_party.plan_agreement.create` function passes the first 
      two parameters and somehow we need to add the client_id 
  */
  console.log('client plan activated');
  active_client_plan(plan_document, client_id);
};

about 4 years ago · Juan Pablo Isaza Report

0

The traditional way is to use a closure. Define the functions inside the parent's scope so that they can access the client_id as an enclosed variable (kind of like global variables):

const create_plan_agreement = (req, res) => {
    // some code
    var client_id = req.auth.client_id;


    const update_plan_agreement = (err, plan_document) => {
        console.log('plan activated, send notification to the client');
        third_party.plan_agreement.update(plan_document, send_agreement_notification);
    };

    const send_agreement_notification = (err, plan_document) => {
        console.log('client plan activated');

        // Note: this function can access client_id
        // because it is in scope
        active_client_plan(plan_document, client_id);
    };

    third_party.plan_agreement.create({}, update_plan_agreement);
};

Closures are to scopes what objects are to classes. A closure is an instance of a scope. So unlike regular global variable, each call to create_plan_agreement() will create its own closure with its own copy of client_id.

With modern javascript it is often easier to handle this with Promises. Convert legacy functions to return a Promise and then you can use async/await:

const create_plan_agreement = async (req, res) => {
    // some code
    var client_id = req.auth.client_id;
    try {
        var plan_document = await plan_agreement_create({});
        var updated_plan_document = await update_plan_agreement(plan_document);
        send_agreement_notification(updated_plan_document, client_id);
    }
    catch (err) {
        // handle errors here.
    }
};

const plan_agreement_create = (arg) {
    return new Promise ((ok, fail) => {
        third_party.plan_agreement.create({}, (err, result) => {
            if (err) {
                return fail(err);
            }
            ok(result);
        });
    })
}

const update_plan_agreement = (plan_document) => {
    return new Promise ((ok, fail) => {
        third_party.plan_agreement.update(plan_document, (err, result) => {
            if (err) return fail(err);
            ok(result);
        });
    });
};

const send_agreement_notification = (plan_document, client_id) => {
    active_client_plan(plan_document, client_id);
};

Or even without async/await Promises still make callbacks easier to use:

const create_plan_agreement = async (req, res) => {
    // some code
    var client_id = req.auth.client_id;

    plan_agreement_create({})
        .then(doc => update_plan_agreement(doc));
        .then(doc => {
            send_agreement_notification(doc, client_id)
        })
        .catch(err => {
            // handle errors here.
        });
};
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!