Reputation: 1318
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
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
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
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