3

I want to wrap Fetch API in fp-ts in some manner:

  1. create request
  2. check status
  3. if status is ok - return json
import * as TE from 'fp-ts/lib/TaskEither';
import * as E from 'fp-ts/lib/Either';
import { flow } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';

const safeGet = (url: string): TE.TaskEither<Error, Response> => TE.tryCatch(
  () => fetch(url),
  (reason) => new Error(String(reason))
);

const processResponce = flow(
  (x: Response): E.Either<Error, Response> => {
    return x.status === 200
      ? E.right(x)
      : E.left(Error(x.statusText))
  },
  TE.fromEither
);

export const httpGet = (url: string): TE.TaskEither<Error, Response> => pipe(
  safeGet(url),
  TE.chain(processResponce)
);

With this example after running httpGet I get an Response and need to eval .json() method manually. So how can I avoid this behavior and get json inside pipe?

  • How are you calling `httpGet`? What response are you seeing? – Shaun Luttin Jun 02 '20 at 15:55
  • const getActivities = httpGet('https://fakerestapi.azurewebsites.net/api/Activities/1'); getActivities().then(x => console.log(x)); And I got: { _tag: 'Right', right: Response { size: 0, timeout: 0, [Symbol(Body internals)]: { body: [Gunzip], disturbed: false, error: null }, [Symbol(Response internals)]: { url: 'https://fakerestapi.azurewebsites.net/api/Activities/1', status: 200, statusText: 'OK', headers: [Headers], counter: 0 } } } – Arseniy Prosvirnin Jun 02 '20 at 16:03

1 Answers1

3

Just chain this into your flow?

const safeJson = <T = unknown>(resp: Response): TE.TaskEither<Error, T> => TE.tryCatch(
  () => resp.json(),
  (reason) => new Error(String(reason))
);
Alfred Young
  • 397
  • 1
  • 3
  • 15