There are many ways one could write such a function. I know your goal is to learn how to use pipe
, but let me first show a technique that starts with something similar to your functions:
const getSQLQuery = ( { lang } ) => `My query is ${lang}`;
const getMarket = country => `my country is ${country}`;
const flipAndJoin = pipe(reverse, join(' and '))
const comp = useWith(unapply(flipAndJoin), [getMarket, getSQLQuery])
comp("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
Now the questions are:
- Why does your function not work?
- How can you make it work?
- How do you make
pipe
work as desired?
Why does your function not work?
It's simple: pipe
takes a number of functions as parameters, with at least one required. The first argument you supply is getSQLQuery( queryParams )
, which is the result of calling getSQLQuery
with an argument. That is a string, not a function. So when you try to wrap this in pipe
, it fails. (The note about 'arity' has to do with the internals of Ramda: it uses the first function to pipe
in order to determine how many parameters the resulting function should take.)
How can you make it work?
I gave an answer up above. The answer from MarioF does so with minimal change to your initial functions.
But none of these are as simple as
const comp2 = (country, queryParams) =>
`My query is ${queryParams.lang} and my country is ${country}`
comp2("Spain", {lang: "uk"}); //=> ""My query is uk and my country is Spain"
How do you make pipe
work as desired?
You need to realize what pipe
does.
Think of a function like this:
const getUpperAddr(userName, collection) {
const configStr = getUserConfig(userName, collection);
const config = JSON.parse(configStr);
const address = prop('address')(config);
const addrLine1 = prop('addrLine1')(address);
const upperAddr = toUpper(addrLine1);
return upperAddr;
}
Forgetting the details, especially of how getUserConfig
works, and forgetting any potential errors, we can see one interesting feature of this function: each successive local variable is created by applying a function to the one before. The only exception to this is the first one, which uses the parameters to the function. The result is the final local variable.
pipe
is simply a way to make this more declarative, and remove the need for all the local variables (and even the parameter names.) This is equivalent:
const getUpperAddr = pipe(
getUserConfig,
JSON.parse,
prop('address'),
prop('addrLine1'),
toUpper
);
This has the same signature as the above and returns the same result for the same input. If you can write your function in the first format, you can mechanically change to pipe
. After a while, this becomes second nature, and you can skip the first step.