Home > Enterprise >  Simplify fp-ts function
Simplify fp-ts function

Time:06-02

I have this function:

export const getProducts = makeRequest(
  /** Your query */
  `asasd*[_type == "product"] {
      _id,
      title
    }`,
  /** Optionally transform the response */
  (i) => i,
  /** Validate exact type */
  D.array(Product)
);

which is of type:

const getProducts: TaskEither<Error, {
    _id: string;
    title: string;
}[]>

This is used in a Next.js API route like this:

export default async (
  _: NextApiRequest,
  res: NextApiResponse<Array<Product>>
) => {
  const request = await getProducts();
  return pipe(
    request,
    E.fold((v) => res.status(400).end(v.message), res.status(200).json)
  );
};

It work, but how can I simplify the last function? I would like for await getProducts() to be inline in the pipe, so I don't have to do the request assignment up front.

CodePudding user response:

You can use map from the Task module:

import * as T from 'fp-ts/Task'

export default async (
  _: NextApiRequest,
  res: NextApiResponse<Array<Product>>;
) => pipe(
  request,
  T.map(E.fold((v) => res.status(400).end(v.message), res.status(200).json))
)();

pipe(request, T.map(...))) returns a Task, so you must call it at the end so that it is executed.

If you really wanted to avoid the () at the end, you could do something like this:

const runTask = async <A>(task: T.Task<A>): Promise<A> => task();

export default async (
  _: NextApiRequest,
  res: NextApiResponse<Array<Product>>;
) => pipe(
  request,
  T.map(E.fold((v) => res.status(400).end(v.message), res.status(200).json)),
  runTask
);
  • Related