Skip to content

fix(inject-is-intersecting): Fix encapsulation, SSR safety, and shared-element subscription teardown#675

Open
endlacer wants to merge 5 commits intongxtension:mainfrom
endlacer:feature/fix-inject-is-intersecting
Open

fix(inject-is-intersecting): Fix encapsulation, SSR safety, and shared-element subscription teardown#675
endlacer wants to merge 5 commits intongxtension:mainfrom
endlacer:feature/fix-inject-is-intersecting

Conversation

@endlacer
Copy link
Copy Markdown
Contributor

  1. observe() now returns Observable instead of exposing the internal Subject directly, preventing consumers from calling .next(), .error(), or .complete() externally
  2. intersect() removed from the public interface and made private — it is an internal callback and should not be callable from outside the service
  3. Added isPlatformBrowser() guard in createObserver() to prevent a ReferenceError crash in SSR environments where IntersectionObserver is unavailable
  4. Added ref-counting via observerCounts so that when multiple components observe the same element, a single component being destroyed no longer completes the shared Subject and silently cuts off all other consumers
  5. Fixed incorrect first argument to assertInjector (injectDestroy → injectIsIntersecting) so injection context errors report the correct origin

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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 refines the injectIsIntersecting functionality by enhancing its robustness and developer experience. The changes focus on improving encapsulation, ensuring compatibility with Server-Side Rendering, and correctly managing shared resources to prevent unexpected behavior when multiple parts of an application interact with the same observed elements. These updates lead to a more stable and predictable API.

Highlights

  • Improved Encapsulation: The observe() method now returns an Observable<IntersectionObserverEntry> instead of directly exposing the internal Subject, preventing external manipulation. Additionally, the intersect() method has been made private, restricting its use to internal service logic.
  • SSR Safety: A isPlatformBrowser() guard has been added to createObserver() to prevent ReferenceError crashes in Server-Side Rendering (SSR) environments where IntersectionObserver is not available.
  • Robust Shared-Element Subscription Teardown: Reference counting via observerCounts has been implemented. This ensures that when multiple components observe the same element, the IntersectionObserver is only truly unobserved and disconnected when all consumers have unsubscribed, preventing premature termination of other active subscriptions.
  • Corrected assertInjector Context: The first argument to assertInjector was fixed from injectDestroy to injectIsIntersecting, ensuring that injection context errors report the correct origin.
Changelog
  • libs/ngxtension/inject-is-intersecting/src/inject-is-intersecting.spec.ts
    • Updated existing test calls to the intersect method to account for its new private visibility using type assertion.
    • Added comprehensive tests for the IsInViewportService to verify the new reference counting logic for observe and unobserve methods, ensuring correct behavior when multiple components observe the same element.
  • libs/ngxtension/inject-is-intersecting/src/inject-is-intersecting.ts
    • Replaced injectDestroy import with Observable from rxjs.
    • Modified injectIsIntersecting to return an Observable instead of a Subject, enhancing encapsulation.
    • Corrected the first argument in assertInjector from injectDestroy to injectIsIntersecting for accurate error reporting.
  • libs/ngxtension/inject-is-intersecting/src/is-in-viewport.service.ts
    • Introduced PLATFORM_ID and isPlatformBrowser to prevent IntersectionObserver errors in SSR environments.
    • Implemented a reference counting mechanism (observerCounts) to manage shared IntersectionObserver instances, ensuring that an element is only unobserved when all consumers have unsubscribed.
    • Changed the observe method to return an Observable instead of directly exposing the internal Subject, enhancing encapsulation.
    • Made the intersect and disconnect methods private to restrict external access.
    • Updated the IsInViewportServiceInterface to reflect the new observe return type and the removal of intersect from the public interface.
Activity
  • No human activity has occurred on this pull request yet.
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
Copy Markdown

nx-cloud bot commented Mar 17, 2026

View your CI Pipeline Execution ↗ for commit a659d6f

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

☁️ Nx Cloud last updated this comment at 2026-03-28 19:29:36 UTC

Copy link
Copy Markdown

@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 several important fixes and improvements to inject-is-intersecting. The changes correctly address encapsulation by returning an Observable instead of a Subject and making internal methods private. SSR safety is improved by adding a platform check before using IntersectionObserver. The introduction of reference counting for element observers is a great fix to prevent premature teardown when an element is shared. The tests have been updated accordingly, and a new test suite for the reference counting logic has been added, which is excellent. I have one suggestion to improve the robustness of the unobserve method's logic.

@endlacer
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown

@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 several excellent improvements to inject-is-intersecting, including fixes for encapsulation, SSR safety, and subscription teardown logic using reference counting. The changes are well-implemented and include corresponding tests for the new logic. I've suggested a minor refactoring in IsInViewportService to improve code clarity. Overall, this is a great set of improvements.

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