# @idiosync/fswitch

> A functional switch statement with familiar syntax

Latest version **1.0.25** (published 2021-08-12) · ISC license · 0 weekly downloads

## Install

```sh
npm install @idiosync/fswitch
pnpm add @idiosync/fswitch
yarn add @idiosync/fswitch
bun add @idiosync/fswitch
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.25 |
| Published | 2021-08-12 |
| First published | 2020-05-28 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 39.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | James Trickey |
| Maintainers | idiosync |
| Keywords | functional, fswitch, switch, statement, conditional, redux-saga, server, status |

## Links

- npm: https://www.npmjs.com/package/@idiosync/fswitch
- Repository: https://github.com/trickeyd/fswitch
- npm.io page: https://npm.io/package/@idiosync/fswitch

## Alternatives

- [@reckona/mreact-store](https://npm.io/package/@reckona/mreact-store.md) — 976 weekly downloads
- [regular-state](https://npm.io/package/regular-state.md) — 410 weekly downloads
- [@pacote/flux-actions](https://npm.io/package/@pacote/flux-actions.md) — 65 weekly downloads
- [@pilotlab/lux-debug](https://npm.io/package/@pilotlab/lux-debug.md) — 39 weekly downloads
- [vue-persist-state](https://npm.io/package/vue-persist-state.md) — 19 weekly downloads

## Recent versions

- 1.0.25 (latest) — 2021-08-12
- 1.0.24 — 2020-11-18
- 1.0.23 — 2020-11-18
- 1.0.22 — 2020-11-18
- 1.0.21 — 2020-11-18
- 1.0.20 — 2020-08-07
- 1.0.19 — 2020-07-21
- 1.0.18 — 2020-07-06
- 1.0.17 — 2020-06-18
- 1.0.16 — 2020-06-16
- 1.0.15 — 2020-06-07
- 1.0.14 — 2020-06-07
- 1.0.13 — 2020-06-02
- 1.0.12 — 2020-06-02
- 1.0.11 — 2020-06-02
- … 11 more at https://npm.io/package/@idiosync/fswitch/versions

## README

[![NPM Version][npm-image]][npm-url]

# fSwitch

<h3>A functional switch statement - by <a href="https://www.npmjs.com/~idiosync"><img width="100px" height="31px" valign="middle" src="https://storage.googleapis.com/idiosync-web-images/telescope/idiosync_very_small_white_bg.png"></a></h3>

Initially created for handling server statuses in a nice readable way, it generalises as a system for
implementing complex conditional code in a easy-to-read and self-documenting manner.

```js
// use with redux-saga
yield fSwitch(res.status,
  [SUCCESS, () => put(successAction)],
  [FAIL, () => put(failAction)],
  () => put({ type: 'error', error: new Error('summin went wrong') })
)
```

## Installation

yarn:

```bash
$ yarn add @idiosync/fswitch
```

npm:

```bash
$ npm i @idiosync/fswitch
```

## Basic use

The fSwich function accepts an input followed by a series of conditional functions and callbacks. Like a switch statement the first
passing case terminates the process. Finally, a default callback can be passed.

```js
import { fSwitch, fCase, fDefault } from "@idiosync/fswitch"

const person = { age: 45, name: James };

const NAME_IS_RICHARD = person => person.name === 'rechard'
const IS_YOUNGER_THAN_18 = person => person.age < 18

fSwitch(person,
  fCase(NAME_IS_RICHARD, person => saveToRichardPool(person)),
  fCase(IS_YOUNGER_THAN_18, person => tooYoung(person),
  fDefault(person => person.isHappy = true)
)
```

The above statement can also be written in a short from

```js
fSwitch(
  person,
  [NAME_IS_RICHARD, (person) => saveToRichardPool(person)],
  [IS_YOUNGER_THAN_18, (person) => tooYoung(person)],
  (person) => (person.isHappy = true)
);
```

The fSwitch function returns whatever is returned by the successful callback.
Amongst other things this can useful for asynchronous effects.

```js
// await promise returned by successful callback
await fSwitch(
  input,
  fCase(SOME_STATE, async (input) => fetch(input)),
  fDefault(async (input) => fetch(input))
);
```

## Server status codes

fSwitch was initially created for dealing with server status codes in
redux-saga, so I will use that as an example.

All common server codes are supported and listed here: [responses].

```js
// import some error cases
import { SUCCESS, FAIL } from "@idiosync/fswitch";

// create our own conditional if we needed
// (although 404 and all other common codes are actually in above file too)
const IS_404 = (status) => status === 404;

function* fetchUserInfoSaga() {
  const res = yield fetch(url);

  yield fSwitch(
    res.status,
    [SUCCESS, () => put(successAction)],
    [IS_404, () => put(server404Action)],
    [FAIL, () => put(failAction)],
    () => put({ type: "error", error: new Error("summin went wrong") })
  );
}
```

If you need a more complex callback you can return a generator or another saga.
This allows you to effectively yield from the callback

```js
import { fSwitch, SUCCESS } from "fswitch";
import { put, call } from "redux-saga/effects";

function* fetchUserInfoSaga() {
  const res = yield fetch(url);

  yield fSwitch(
    res.status,
    [
      SUCCESS,
      // callback returns a generator wrapped with saga's "call" function
      (status) =>
        call(function* () {
          if (status === 202) {
            yield put(someAction);
          } else {
            yield put(someOtherAction);
          }
        }),
    ],
    () => put(failAction)
  );
}
```

Remember that once a case passes the later ones are not called, so if you want to use SUCCESS or FAIL conditions
then you will have to handle individaul calls first.

```js
fSwitch(
  res.status,
  [SUCCESS, handleSuccess],
  [s200, handle200] // <--- this line will never be reached
);
```

## Combiners

These are functions that combine multiple conditions with and / or logic.

```js
fSwitch(
  status,
  [or(s200, s202), handleSuccess],
  [and(isMoreThan202, isLessThan300), handleSuccessDifferently],
  [FAIL, handleFail]
);
```

## Try/Catch

For the sake of pretty syntax I have added an optional try/catch wrapper. If you use this you
MUST use the catch function returned by try or fSwitch will never be called

```js
  yield fSwitch.try(res.status,
    [ SUCCESS, () => throw new Error("error")],
    () => defaultAction()
  ).catch(
    error => handleError(error)   // <-- error is caught here
  )
```

[npm-image]: https://img.shields.io/npm/v/@idiosync/fswitch
[npm-url]: https://www.npmjs.com/package/@idiosync/fswitch
[responses]: https://github.com/trickeyd/fswitch/blob/master/src/cases/responses.js

---
_Source: https://npm.io/package/@idiosync/fswitch · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
