Skip to content

No-throw mode for scopeBind #666

@AlexandrHoroshih

Description

@AlexandrHoroshih

Proposal

Add an option for scopeBind to supress its exception in case, when there is no active scope.

const maybeBound = scopeBind(event, { safe: true })

In this case, if scopeBind called with safe: true and there is no scope, then scopeBind just returns original event or a function, which calls original event (just like when scope is found)

Use case

scopeBind is meant to be used to bind event or effect to a scope to be called later and the most common use case is to build a bridge of effector events to other reactive source, like websocket, browser api, etc

It works quite well, when used like this:

const connectSocketFx = attach({
 source: $socket,
 effect(socket) {
   socket.on("message", scopeBind(messageReceived))
 }
})

sample({
 clock: appStarted,
 target: connectSocketFx
})

// later
const scope = fork()

await allSettled(appStarted, {scope})

This way it is possible to set scope once, when app is initialized and all related subscriptions will also work in correct scope, which is also useful for tests

But if app doesn't use scopes and only needs Fork API for tests, then scopeBind usage is problematic because it throws exception, when scope is not found

And to allow usage both with and without scope users are required to write something like this:

const safeBind = (event) => {
 try {
   return scopeBind(event)
 } catch(e) {
   return event
 }
}

// later
const connectSocketFx = attach({
 source: $socket,
 effect(socket) {
   socket.on("message", safeBind(messageReceived))
 }
})

The built-in option would allow solving these cases without custom helpers

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRequest for Comments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions