This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
getExchangeRatesForCountry(CountryCode.GGG).then(console.log); | |
// => It returns our failed request | |
// The error is wrapped inside of a TaskEither monad | |
{ | |
_tag: 'Left', | |
left: Error: Request failed with status code 400 | |
at createError (/Users/code/javascript/functional-js/node_modules/axios/lib/core/createError.js:16:15) | |
at settle (/Users/code/javascript/functional-js/node_modules/axios/lib/core/settle.js:17:12) | |
at IncomingMessage.handleStreamEnd (/Users/code/javascript/functional-js/node_modules/axios/lib/adapters/http.js:236:11) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
getExchangeRatesForCountry(CountryCode.USD).then(console.log); | |
// => It returns our validated response | |
// wrapped inside of a TaskEither monad | |
{ | |
_tag: 'Right', | |
right: { | |
rates: { | |
CAD: 1.4069981584, | |
HKD: 7.7505524862, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getExchangeRatesForCountry = (countryCode: CountryCode) => | |
pipe( | |
// tryCatch transforms our Promise that may reject to a Promise that never rejects and returns an Either instead | |
taskEither.tryCatch( | |
// We need an anonymous function here because we can only use tryCatch with functions that return Lazy<Promise<any>> | |
() => fetchExchangeRatesForCountry(countryCode), | |
either.toError | |
), | |
taskEither.chain( | |
// flow => function composition (from left to right) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fetchExchangeRatesForCountry = async ( | |
cc: CountryCode | |
): Promise<ExchangeRates> => { | |
const res = await axios.get( | |
`https://api.exchangeratesapi.io/latest?base=${cc}` | |
); | |
return res.data as ExchangeRates; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const validateExchangeRates = (countryCode: CountryCode) => ( | |
response: ExchangeRates | |
): either.Either<Error, ExchangeRates> => { | |
return response.base === countryCode | |
? either.right(response as ExchangeRates) | |
: either.left( | |
Error( | |
`Invalid exchange rates data! Expected ${countryCode} but got ${response.base}` | |
) | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { either, taskEither } from "fp-ts"; | |
import { flow } from "fp-ts/lib/function"; | |
import { pipe } from "fp-ts/lib/pipeable"; | |
import axios from "axios"; | |
/** | |
* In this real life example we fetch data from an API and validate the result with the usage of Either and TaskEither | |
*/ | |
enum CountryCode { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const APIRequestWithValidation = (validator) => (...requestArgs) => | |
pipe( | |
taskEither.tryCatch(() => makeApiRequest(...requestArgs), either.toError), | |
taskEither.chain(flow(validator, taskEither.fromEither)) | |
)(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as E from "fp-ts/lib/Either"; | |
import * as O from "fp-ts/lib/Option"; | |
import { RouteHandler, r, useMiddleware, Middleware, HttpRequest } from "@zaetrik/omicron"; | |
const toOption: Middleware = (req: HttpRequest): E.Either<Error, O.Option<RequestBody>> => | |
E.tryCatch(() => | |
O.some(req.body), E.toError); | |
const routeHandler: RouteHandler = r | |
("/") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as t from "io-ts"; | |
import * as E from "fp-ts/lib/Either"; | |
import { pipe } from "fp-ts/lib/pipeable"; | |
import { | |
RouteHandler, | |
r, | |
useMiddleware, | |
Middleware, | |
HttpRequest | |
} from "@zaetrik/omicron"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as omicron from "@zaetrik/omicron"; | |
import { IO } from "fp-ts/lib/IO"; | |
const indexHandler = omicron.r | |
("/") // Path | |
("GET") // HTTP method | |
((req) => "Hello 👋") // The handler function | |
((req, error) => `Oops! An error occured ⚠️ => ${error.message}`); // The error handler function | |
const listener = omicron.httpListener({ |
OlderNewer