Skip to content

feat(create-notifier): add support for dependencies#661

Open
endlacer wants to merge 2 commits intongxtension:mainfrom
endlacer:feature/create-notifier-signal-deps
Open

feat(create-notifier): add support for dependencies#661
endlacer wants to merge 2 commits intongxtension:mainfrom
endlacer:feature/create-notifier-signal-deps

Conversation

@endlacer
Copy link
Contributor

@endlacer endlacer commented Feb 4, 2026

#535

Added options.deps where signals can be specified, that trigger the notifier

// Emit immediately (default behavior)
notifier = createNotifier({
	deps: [someSignal],
	depsEmitInitially: true, // starts at 1 (default)
});

// Don't emit initially
notifier = createNotifier({
	deps: [someSignal],
	depsEmitInitially: false, // starts at 0
});

Made it so, that the value inside notify() also increases when the signals emit

@gemini-code-assist
Copy link

Summary of Changes

Hello @endlacer, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the createNotifier utility by introducing a powerful dependency tracking mechanism. Developers can now configure a notifier to automatically react to changes in other Angular signals, providing a more reactive and less manual way to trigger updates. Additionally, fine-grained control over the initial emission behavior when dependencies are present has been added, making the utility more flexible and adaptable to various use cases.

Highlights

  • Dependency Tracking for Notifiers: The createNotifier utility now accepts a deps option, allowing it to automatically trigger notifications when any of the specified Angular signals change.
  • Configurable Initial Emission: A new depsEmitInitially option has been added to control whether a notifier with dependencies emits immediately upon creation (defaulting to true) or starts at 0 and only emits on subsequent dependency changes or manual notify() calls.
  • Enhanced notify() Behavior: The notify() method now consistently increments the internal counter, ensuring that both manual triggers and dependency changes contribute to the notifier's value.
  • Comprehensive Documentation Update: The createNotifier documentation has been significantly expanded to include detailed explanations and code examples for the new dependency tracking features and initial emission control.
  • Robust Test Coverage: New unit tests have been introduced to validate the correct behavior of createNotifier when using the deps option, both with and without depsEmitInitially.
Changelog
  • docs/src/content/docs/utilities/Signals/create-notifier.md
    • Added endlacer to contributors.
    • Restructured content with "Features", "Common Use Cases", and "Basic Usage" headings.
    • Introduced a new "Dependency Tracking" section, detailing basic usage, multiple dependencies, and controlling initial emission with code examples.
    • Clarified the explanation for avoiding initial effect execution.
  • libs/ngxtension/create-notifier/src/create-notifier.spec.ts
    • Imported signal from @angular/core.
    • Added new test cases to verify createNotifier's behavior with options.deps, ensuring it increments on both manual notify() calls and dependency signal changes.
    • Included a test case for options.deps with depsEmitInitially: false to confirm correct initial value and subsequent increments.
  • libs/ngxtension/create-notifier/src/create-notifier.ts
    • Modified createNotifier to accept an optional CreateNotifierOptions object, including deps (an array of Signal<any>) and depsEmitInitially (boolean).
    • Implemented linkedSignal to manage the notifier's internal state, allowing it to react to changes in specified deps.
    • Configured linkedSignal's source function to track dependencies and set the initial value based on deps and depsEmitInitially.
    • Defined linkedSignal's computation to increment the notifier's value when dependencies change.
    • Ensured equal: () => false in linkedSignal to guarantee all downstream consumers are notified on every change.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@nx-cloud
Copy link

nx-cloud bot commented Feb 4, 2026

View your CI Pipeline Execution ↗ for commit 374f06d

Command Status Duration Result
nx affected --target=build --parallel=3 --exclu... ✅ Succeeded 25s View ↗
nx affected --target=test --parallel=3 --exclud... ✅ Succeeded 23s View ↗
nx affected --target=lint --parallel=3 ✅ Succeeded 52s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-08 17:18:36 UTC

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces dependency tracking to createNotifier, which is a great enhancement. The implementation is clever, but it currently relies on linkedSignal, a private Angular API. This poses a significant risk for library maintenance, and I've flagged it as a critical issue. Additionally, I've provided suggestions to improve the TypeScript typings for a better developer experience and corrected an error in the documentation example. The new tests are well-written and effectively cover the new functionality.

Comment on lines 26 to 31
options?.deps?.forEach((dep) => dep()); // Track all dependencies

// - when deps exist, the notifier should start at 1, because it immediatley emits.
// -without any deps, it is only based on increments. and those should start at 0.
return options?.deps?.length && options?.depsEmitInitially ? 1 : 0;
},

Choose a reason for hiding this comment

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

medium

After the options object is merged with DEFAULT_OPTIONS on line 20, it is guaranteed to be defined. Therefore, the optional chaining (?.) used here is unnecessary and can be misleading. Removing it would improve code clarity.

Additionally, there is a small typo in the comment on line 28 ('immediatley' should be 'immediately').

Suggested change
options?.deps?.forEach((dep) => dep()); // Track all dependencies
// - when deps exist, the notifier should start at 1, because it immediatley emits.
// -without any deps, it is only based on increments. and those should start at 0.
return options?.deps?.length && options?.depsEmitInitially ? 1 : 0;
},
options.deps.forEach((dep) => dep()); // Track all dependencies
// - when deps exist, the notifier should start at 1, because it immediately emits.
// -without any deps, it is only based on increments. and those should start at 0.
return options.deps.length && options.depsEmitInitially ? 1 : 0;
},

@eneajaho
Copy link
Collaborator

eneajaho commented Feb 7, 2026

Hi @endlacer
I was thinking if we can do something like:
createNotifier.withDeps([dep1, dep2]) instead of modifying the current function. The reason is because we go from creating a signal to creating a linkedSignal and the initial function which was cheap imo now will get heavier and have more things to take care of. What do you think?

@endlacer endlacer force-pushed the feature/create-notifier-signal-deps branch from 85c615f to 374f06d Compare February 8, 2026 17:16
@endlacer
Copy link
Contributor Author

endlacer commented Feb 8, 2026

Hi @endlacer I was thinking if we can do something like: createNotifier.withDeps([dep1, dep2]) instead of modifying the current function. The reason is because we go from creating a signal to creating a linkedSignal and the initial function which was cheap imo now will get heavier and have more things to take care of. What do you think?

true, but i would prefer the option-syntax though.
I changed it now, check it out :)

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.

2 participants