Pranay Tripathi
Pranay Tripathi

Reputation: 1882

Jest throwing TyperError: Expected a function when using lodash pipe/flow

I have following code:

function sort() {
   let array1 = [{ value:1 }, { value:2 }, { value:3 }];
   let array2 = [{ code:1 }, { code:2 }, { code:3 }];
   const constructSortedArray = pipe(
     sortBy(array1, element => element.value),
     sortedArray1 => sortedArray1.concat(array2)
   );
   return constructSortedArray();
 }

I m using lodash/fp/flow as pipe alias and lodash/sortBy. When running the code, the function works fine but when testing the code with jest I get following error on pipe:

TypeError: Expected a function 

> 73 |     const constructSortedArray = pipe(

I have tried setting the testEnviornment as jsdom and node but its not helpful. The automock is also disabled for jest.

Any help is appreciated.

Upvotes: 1

Views: 1340

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

When you call sortBy it returns the results, and not a function. You can fix by using an arrow function, and calling the piped function with array1 as argument.

Note: lodash doesn't have a _.pipe() method (it's named _.flow()), but lodash/fp does (it's an alias of _.flow()).

const { flow, sortBy } = _;

function sort() {
  let array1 = [{ value:1 }, { value:2 }, { value:3 }];
  let array2 = [{ code:1 }, { code:2 }, { code:3 }];
  const constructSortedArray = flow(
    arr => sortBy(arr, element => element.value),
    sortedArray1 => sortedArray1.concat(array2)
  );
  return constructSortedArray(array1);
}
 
console.log(sort());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

A cleaner option would be to user _.partialRight() to return a function with the right most parameter already applied:

const { flow, partialRight, sortBy, concat } = _;

function sort() {
  let array1 = [{ value:1 }, { value:2 }, { value:3 }];
  let array2 = [{ code:1 }, { code:2 }, { code:3 }];
  
  const constructSortedArray = flow(
    partialRight(sortBy, element => element.value),
    partialRight(concat, array2)
  );

  return constructSortedArray(array1);
}

console.log(sort());
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

And the cleanest way would be to user lodash/fp, because all functions are auto-curried, and the parameters are in the correct order:

const { pipe, partialRight, sortBy, concat } = _;

function sort() {
  let array1 = [{ value:1 }, { value:2 }, { value:3 }];
  let array2 = [{ code:1 }, { code:2 }, { code:3 }];
  
  const constructSortedArray = pipe(
    sortBy(element => element.value),
    partialRight(concat, [array2])
  );

  return constructSortedArray(array1);
}

console.log(sort());
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

Upvotes: 3

Related Questions