createEffect()

Creates an EffectCreator.

One of the most common patterns when performing side effects inside the epics is dispatching some "start" event before the side effect and "error" or "success" event when the side effect has finished its work.

Effect creator does that automatically. When called, it returns an observable stream of a start event, then it calls the provided effect function and after that it emits the "success" or "error" event.

Definition

type createEffect<Payload, Result> = (
  description: string,
  effect?: (payload: Payload) => Promise<Result> | Result,
  condition?: (payload: Payload) => boolean
) => EffectCreator<Payload, Result>

type EffectCreator<Payload, Result> = {
  (payload: Payload): Result  
  start: EventCreator<Payload>
  success: EventCreator<Result>
  fail: EventCreator<any>
  complete: EventCreator<void>
  getType(): string
  use(effectFn: (payload) => Promise<Result> | Result): EffectCreator<Payload, Result>
}

Usage

Creates an EffectCreator. Accepts a description, a side effect function (optional) and a condition function (defaults to () => true).

import { createEffect } from 'stapp'
import { switchMap } from 'rxjs'

const payEffect = createEffect(
  // Effect descriptioo=n
  'Perform payment',

  // Effect function, optional
  params => fetch(`pay${toQuery(params)}`),

  // Condition can be used to disable an effect. Also optional
  () => process.env.ENV === 'browser'
)

// Usage in an epic:
const payEpic = submit.epic((event$, _, { getState }) => event$.pipe(
  switchMap(() => payEffect(getState()))
))

When called effect creator returns a stream of three events: start, then success or fail after completing side effect and finally, the complete event.

The condition argument can be used to disable an effect on some conditions.

use()

Replaces an effect function used by EffectCreator in situ. Might be useful while testing.

const effect = createEffect('Some side request', sideRequest)

test('some test', async () => {
  const mock = jest.fn(x => x * 2)
  effect.use(mock)
  const events = []

  await effect(1).forEach(ev => events.push(ev))

  expect(mock).toBeCalledWith(1)

  expect(events).toEqual([
    effect.start(1),
    effect.success(2),
    effect.complete()
  ])
})

start

Event emitted by effect creator before performing a side effect.

const effect = createEffect('Some side request', sideRequest)
const startEffectEpic = effect.start.epic(start$ => start$.pipe(...))

success

Event emitted by effect creator after resolving the Promise, returned by the side effect function.

const effect = createEffect('Some side request', sideRequest)
const successEffectEpic = effect.success.epic(success$ => success$.pipe(...))

fail

Event emitted by effect creator if the side effect function failed in some way.

const effect = createEffect('Some side request', sideRequest)
const failEffectEpic = effect.fail.epic(fail$ => fail$.pipe(...))

complete

Event emitted by effect creator after completion of a side effect. Emitted right after success or fail event.

const effect = createEffect('Some side request', sideRequest)
const finallyEpic = effect.complete.epic(complete$ => complete$.pipe(...))

getType()

Returns the type of a start event.

const effect = createEffect('Some side request', sideRequest)

effect.getType() === effect.start.getType() // true

results matching ""

    No results matching ""