Skip to content

feat!: createEffect() upgrade#600

Open
e-oz wants to merge 2 commits intongxtension:mainfrom
e-oz:create-effect-upgrade
Open

feat!: createEffect() upgrade#600
e-oz wants to merge 2 commits intongxtension:mainfrom
e-oz:create-effect-upgrade

Conversation

@e-oz
Copy link
Contributor

@e-oz e-oz commented May 31, 2025

  • Support Promise as input value;
  • The generator callback now has the second argument, callbacks. It contains an object with callbacks success and error - the observable you provide to createEffect() can use them to notify the effect caller;
  • Now createEffect() accepts the second argument with fields:
    • onSuccess?: (v?: unknown) => void - will be called when callbacks.success is called;
    • onError?: (v?: unknown) => void - will be called when callbacks.error is called;
    • onFinalize?: () => void - will be called when either callbacks.success or callbacks.error is called;
  • When a signal is passed to the function created by createEffect(), the effect handler is called synchronously and will not be called again with the same value (equal by reference, ===) when the underlying effect() is executed.
  • An effect can now return not only a subscription, but also an observable, using the asObservable() method of the created effect.
    Example:
const myEffect = createEffect<number>((_) => ....);
const obs$ = myEffect.asObservable(5);
  • createEffect() with default options (with retry on errors allowed) was "swallowing" errors. Now the error will be printed to the console in dev mode, and the onError() callback will be called.

BREAKING CHANGE:
Previously, createEffect() would re-subscribe when the effect's handler threw an error, and when the observable passed to the handler threw an error. Now it will only re-subscribe to the handler. If a passed observable throws an error, the effect will not re-subscribe to that observable - you will need to call the effect again. Re-subscribing to an observable that is in an error state might cause endless loops and unexpected behavior.
This change could be considered a bugfix, but if some app was relying on the previous behavior - even if it was erroneous - it would technically be a breaking change for that app.

e-oz added 2 commits May 31, 2025 13:30
* Support Promise as input value;
* The generator callback now has the second argument, `callbacks`. It contains an object with callbacks `success` and `error` - the observable you provide to `createEffect()` can use them to notify the effect caller;
* The second argument of `createEffect()` got new fields:
* * `onSuccess?: (v?: unknown) => void` - will be called when `callbacks.success` is called;
* * `onError?: (v?: unknown) => void` - will be called when `callbacks.error` is called;
* * `onFinalize?: () => void` - will be called when either `callbacks.success` or `callbacks.error` is called;
* When a signal is passed to the function created by `createEffect()`, the effect handler is called synchronously and will not be called again with the same value (equal by reference, `===`) when the underlying `effect()` is executed.

BREAKING CHANGE:
Previously, `createEffect()` would re-subscribe when the effect's handler threw an error,
and when the observable passed to the handler threw an error.
Now it will only re-subscribe to the handler. If a passed observable throws an error,
the effect will not re-subscribe to that observable - you will need to call the effect again.
Re-subscribing to an observable that is in an error state might cause endless loops and unexpected behavior.
…was "swallowing" errors. Now the error will be printed to the console in dev mode, and the `onError()` callback will be called.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant