Jack Ryan
Jack Ryan

Reputation: 1318

Save arguments for later Javascript

The title of this question is probably misleading. I'm having some trouble wrapping my head around this concept. I want to pass all of the arguments into a function, but call it with those arguments later.

I'm currently doing something like this:

function copyRecords(userId, options) {
    const getRecordsWrapper = (userId, options) => () => getRecords(userId, options);
    abstractionService = new MyAbstractionService(getRecordsWrapper);
    ...etc
}

This is where I would save and later call the function:

class MyAbstractionService {
    constructor(getRecords) {
        this.getRecords = getRecords;
    }
    performSomeAction() {
        return this.getRecords();
    }
}

I need to do this because getRecords takes different arguments in different areas, and I want to abstract them into one service without having to pass a bunch of arguments into the service. That will get messy, as I need to do this for some other functions as well.

Am I thinking about this correctly? Is there another way to do this besides having a function return another function which returns my function? Also, not sure if this is important but getRecords returns a Promise. I don't want to start working on the Promise until I'm in the abstraction service later though.

Upvotes: 6

Views: 1663

Answers (3)

Jonas Wilms
Jonas Wilms

Reputation: 138237

As partial application is a common problem, there is a proposal to support that directly in javascript without .bind. If the proposal gets through, it will look like:

new MyAbstractionService(getRecords(userId, options, ...))

Upvotes: 1

Evert
Evert

Reputation: 99525

Using bind() is a good idea. Here's an alternative. Leaving it up to readers which is preferred.

function copyRecords(userId, options) {
  return () => {
    return getRecords(userId, options);
  }
};

Note that this is pretty much identical to:

function copyRecords(userId, options) {
  return getRecords.bind(this, userId, options);
};

So it comes down to a subjective preference.

Upvotes: 1

haim770
haim770

Reputation: 49095

In functional programming terms, what you're describing is Currying, and in JavaScript you can achieve the simplest idea of it using the bind() function:

const getRecordsWrapper = getRecords.bind(null, userId, options);

The first argument passed to bind is the function context (the this) of the to-be-called-later function, while the rest of the arguments are passed as regular arguments.

If you're looking for a fully-featured functional programming framework in JavaScript, take a look at Ramda.js (for example).

Upvotes: 4

Related Questions