Anas Anas - 2 months ago 11
Javascript Question

Passing arguments while running lodash flow asynchronously

Given the code below, how can I pass id to the applySaveAsync function?

var then = _.curry(function (f, thenable) {
return thenable.then(f);
});

var validateAsync = _.flow(
function () { return _(someCondition).showError(ERROR_01).value(); },
then(function () { return _(anotherCondition).showError(ERROR_02).value(); })
);

var save = _.flow(
validateAsync,
then(applySaveAsync),
then(saveCompleted)
);

function applySaveAsync(id) {
// Saving...
}

save(22); // Calling save function with some id.


I can get the id on the validateAsync function, but I cannot return it back since validateAsync should return a promise.

Any way to achieve that?

Answer

The simplest choice would be not to use _.flow for the definition of validateAsync.
Since validateAsync does not take parameters nor has a result, you should just change the definition of save to not use _.flow:

function save(id) {
    return validateAsync()
    .then(function(){ return applySaveAsync(id) })
    .then(saveCompleted)
}

We could also change validateAsync to pass through the id:

function validateAsync(id) {
    return _(someCondition).showError(ERROR_01).value()  
    .then(function () { return _(anotherCondition).showError(ERROR_02).value(); })
    .then(_.constant(id));
}

and even do that while still using _.flow

var validateAsync = _.flow(
    function(id) { return _(someCondition).showError(ERROR_01).value().then(_.constant(id)); },  
    then(function(id) { return _(anotherCondition).showError(ERROR_02).value().then(_.constant(id)); }) 
);

but I would advise against that since validateAsync is not supposed to be a function that does takes parameters.

Let's write a wrapper function for such instead to let us do the pass-around in a functional way:

function pass(fn) {
    return function(id) {
        return fn().then(function() {
            return id;
        });
    }
}

(if you prefer, you can try to compose that from then, _.constant and more)
so that one can write

var save = _.flow(
    wrap(validateAsync),
    then(applySaveAsync),
    then(saveCompleted)
);