Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No chance to access first value of paramGroup on component load #176

Closed
steinsag opened this issue Dec 10, 2020 · 3 comments
Closed

No chance to access first value of paramGroup on component load #176

steinsag opened this issue Dec 10, 2020 · 3 comments
Labels
Status: Needs Triage We need to properly tag this issue Type: Bug Something that should work doesn't

Comments

@steinsag
Copy link

StackBlitz: https://stackblitz.com/github/steinsag/angular-ngqp?file=src%2Fapp%2Ffilter-list.component.ts
Belonging GitHub repo: https://github.com/steinsag/angular-ngqp

Steps to reproduce:

  • start above app
  • click on button "search param q=123"
    • expected: list only shows values containing 123
    • actual: all values are shown; quickSearch is null on load

Sub-sequent clicks on the buttons or manually entering a different value in quickSearch filter works as expected. If one returns to "home" component, the problem can be reproduced again.

In issue #72, a work-around is described to access the first value of a param group when a component is loaded. Idea is to wrap paramGroup.valueChanges with another observable with a startWith value using something like:

this.paramGroupValues$ = this.paramGroup.valueChanges.pipe(
  startWith(this.paramGroup.value),
  takeUntil(this.ngUnsubscribe)
);

However, this doesn't seem to work, because this.paramGroup.value always returns null on component init.

@steinsag steinsag added Status: Needs Triage We need to properly tag this issue Type: Bug Something that should work doesn't labels Dec 10, 2020
@Airblader
Copy link
Collaborator

Thanks for reporting this and, importantly, providing a StackBlitz! I will take a closer look and a more detailed reply later on, but if you need a way to make this work quickly, this is it:

    this.paramGroupValues$ = defer(() => this.paramGroup.valueChanges.pipe(
      startWith(this.paramGroup.value),
      takeUntil(this.ngUnsubscribe)
    ));

@steinsag
Copy link
Author

I can confirm this work-around resolves the issue!

@Airblader
Copy link
Collaborator

So to explain a bit further, in case it isn't clear now anyway, the difference is essentially the timing of when paramGroup.value is evaluated. In

this.paramGroupValues$ = this.paramGroup.valueChanges.pipe(
  startWith(this.paramGroup.value),
  takeUntil(this.ngUnsubscribe)
);

this happens when the observable is created, not when it is subscribed. At this point ngqp has had no time to synchronize the value from the URL, of course, and thus the value is null. Wrapping this into defer we can make this evaluation "lazy" such that it occurs when the observable is subscribed, which is what we want: upon subscription we track changes, but start once initially with the current value. This is essentially the same as if valueChanges was a ReplaySubject(1) instead of a Subject.

The fact that I posted this wrong in #72 was just an oversight, thanks for correcting it there. :-) I'll also update my comment there afterwards.

All that being said, this does still behave as intended, and I still think changing the semantic of valueChanges isn't ideal and would rather lean towards the idea of adding a value$ observable which is replayed. I've opened #177 for that (and will in turn close this issue).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Needs Triage We need to properly tag this issue Type: Bug Something that should work doesn't
Projects
None yet
Development

No branches or pull requests

2 participants