Skip to main content

What does merge() do?

What merge is

merge() combines several events (or streams) into one. It creates a new event that fires every time any of the source events fires.

A metaphor:

"I have several sources of events, but I want to react to them as one."


A simple example

javascript
import { createEvent, merge } from 'effector' const loginClicked = createEvent() const registerClicked = createEvent() const authStarted = merge([loginClicked, registerClicked]) authStarted.watch(() => console.log('Starting authorization')) loginClicked() // -> "Starting authorization" registerClicked() // -> "Starting authorization"

So authStarted fires on any of these events.


2. What merge returns

merge() returns a new event into which all the events from the array are "fused".

The type of the new event is the union (union) of the source events' payloads.


3. Example with a payload

javascript
const emailLogin = createEvent<{ email: string }>() const phoneLogin = createEvent<{ phone: string }>() const login = merge([emailLogin, phoneLogin]) login.watch((data) => console.log('Login:', data)) emailLogin({ email: 'a@b.com' }) // -> { email: 'a@b.com' } phoneLogin({ phone: '+123456' }) // -> { phone: '+123456' }

Effector doesn't lose data - it just combines the streams. The payload is preserved from each source.


4. You can also combine effects

merge() also works with effects (via .doneData, .fail, .finally, etc.):

javascript
const loadUserFx = createEffect(...) const loadPostsFx = createEffect(...) const dataLoaded = merge([loadUserFx.doneData, loadPostsFx.doneData]) dataLoaded.watch(() => console.log('Something finished loading'))

Handy when you need to react to "anything that finished".


5. A common pattern: combining different events of the same kind

For example, if you have several actions that should lead to the same result:

javascript
const clickedBuy = createEvent() const clickedAddToCart = createEvent() const clickedFavorite = createEvent() const productInteracted = merge([clickedBuy, clickedAddToCart, clickedFavorite]) productInteracted.watch(() => console.log('The user interacted with the product'))

Now it doesn't matter which action exactly, the logic runs the same way.


6. Combining merge with other operators

merge() is often used as the first step before guard() or sample():

javascript
const loginClicked = createEvent() const registerClicked = createEvent() const authClicked = merge([loginClicked, registerClicked]) guard({ source: authClicked, filter: $isAuthEnabled, target: startAuthFx, })

This way you combine all possible ways to trigger one logic flow.


7. Behavior

  • merge() doesn't change the payload;
  • doesn't duplicate events, it just combines them;
  • you can pass an array of any length;
  • it works with any type of event/effect.doneData;
  • the result is a new event that you can subscribe to or route further (forward, sample, guard, etc.).

8. Visually

javascript
[eventA] ─┐ ├──> [merge][target] [eventB] ─┘

Every time eventA or eventB fires, the new combined event fires too.


9. Example from a real application

javascript
const openedFromMenu = createEvent() const openedFromSearch = createEvent() const openedFromLink = createEvent() const pageOpened = merge([openedFromMenu, openedFromSearch, openedFromLink]) pageOpened.watch(() => console.log('Page opened'))

Now you can conveniently log a single pageOpened event, instead of three separate watch calls.


10. Typing merge in TypeScript

Effector infers types carefully:

javascript
const e1 = createEvent<number>() const e2 = createEvent<string>() const merged = merge([e1, e2]) // type of merged: Event<number | string>

That is, the payload is combined into a union. TypeScript correctly knows that merged can carry either a number or a string.


Summary

merge() combines several events (or effects) into one. It creates a new event that fires on any of the source ones, passing their payload "as is".


A formula to remember

merge([A, B, C]) -> D, where D() is called on every A(), B(), C().

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.