Skip to content

Conversation

@markostanimirovic
Copy link
Member

@markostanimirovic markostanimirovic commented Nov 16, 2025

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

Closes #4776

What is the new behavior?

// === providing scoped dispatcher: ===
{ providers: [provideDispatcher()] }

// === dispatching events to the parent/global scope: ===
// scope values: 'self' | 'parent' | 'global' ('self' by default)

const event1 = event('event1');
const event2 = event('event2');

// using Dispatcher:
const dispatcher = inject(Dispatcher);
dispatcher.dispatch(event1(), { scope: 'parent' });

// using injectDispatch:
const dispatch = injectDispatch({ event1 });
dispatch({ scope: 'global' }).event1();

// using toScope:
withEffects((_, events = inject(Events)) => ({
  $: events.on(event1).pipe(
    map(() => [event2(), toScope({ 'parent' })]),
  ),
}))

// using mapToScope:
withEffects((_, events = inject(Events)) => ({
  $: events.on(event1).pipe(
    map(() => event2()),
    mapToScope('global'),
  ),
}))

Does this PR introduce a breaking change?

[ ] Yes
[x] No

@netlify
Copy link

netlify bot commented Nov 16, 2025

Deploy Preview for ngrx-io canceled.

Name Link
🔨 Latest commit f0e87a2
🔍 Latest deploy log https://app.netlify.com/projects/ngrx-io/deploys/6921d5bc452e640008f7a4a0

@netlify
Copy link

netlify bot commented Nov 16, 2025

Deploy Preview for ngrx-site-v19 ready!

Name Link
🔨 Latest commit f0e87a2
🔍 Latest deploy log https://app.netlify.com/projects/ngrx-site-v19/deploys/6921d5bc952bad00086cbc42
😎 Deploy Preview https://deploy-preview-4997--ngrx-site-v19.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@rainerhahnekamp rainerhahnekamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will you provide the updated documentation in a separate PR?

@markostanimirovic
Copy link
Member Author

@rainerhahnekamp Yes, I'll add a new section 'Scoped Events' without changing existing content from the Events page because the previous behavior remained the same.

mapToScope,
toScope,
} from './event-scope';
export { Events, ReducerEvents } from './events-service';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is important for the event tracker in the toolkit. 👍

Copy link
Contributor

@rainerhahnekamp rainerhahnekamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Copy link
Member

@timdeschryver timdeschryver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely! 🤩

Comment on lines 69 to 72
* \@Component({
* \/* ... *\/
* providers: [provideDispatcher()],
* })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to escape these?
In VSCode this gives the following result:

Image
Suggested change
* \@Component({
* \/* ... *\/
* providers: [provideDispatcher()],
* })
* @Component({
* /* ... */
* providers: [provideDispatcher()],
* })

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed unnecessary second backslashes in: \/* ... \/. The first one is required. Otherwise, it's not displayed properly:

Screenshot 2025-11-22 at 16 22 34

Regarding a backslash before the @Component decorator, it's needed to avoid treating @Component as a JSDoc annotation.

* );
* ```
*/
export function toScope(scope: EventScope): EventScopeConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An open question about the naming of this function, sorry I should've mentioned this in the RFC.
What about renaming it to withScope, I think this makes the intent easier to read.

[loadSuccess(), withScope('global')]
// or
[loadSuccess(), scopedTo('global')]

I'm also fine with toScope though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep the toScope name for consistency with mapToScope, but also to distinguish it from SignalStore features that have the with prefix.

In general, this helper is not required (we can directly return [loadedSuccess(), { scope: 'global' }]), but I added it for a bit better DX - to avoid typos and enable autocompletion in IDEs for the scope name. Anyway, mapToScope will be the common way to change the default event scope in the effect, while toScope can be used if we want to have more granular control and have different scopes for success and error events, which would be a rare case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@ngrx/signals/events: Provide Support for Scoped Events

4 participants