Have ideas to improve npm?Join in the discussion! »

    @idiosync/fswitch
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.24 • Public • Published

    NPM Version

    fSwitch

    A functional switch statement - by

    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.

    // 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:

    $ yarn add @idiosync/fswitch

    npm:

    $ 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.

    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

    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.

    // 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.

    // 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

    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.

     
    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.

     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

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

    Install

    npm i @idiosync/fswitch

    DownloadsWeekly Downloads

    55

    Version

    1.0.24

    License

    ISC

    Unpacked Size

    325 kB

    Total Files

    10

    Last publish

    Collaborators

    • avatar