I am trying to create refetch functionality. The problem is that because values$
and retryGetValues
have different subscribers, my component is not re-rendering. How can I make it so that values$
is recalculated when I press my retry button?
export class ExampleComponent {
public values$ = this.getValues()
public retryGetValues() {
this.getValues().pipe(take(1)).subscribe()
}
private getLatestInput = computed(() => this.service.getInput())
private getValues() {
return defer(() => {
return this.service.getValues(this.getLatestInput())
}).pipe(() => {
// What can I do here to make the template re-evaluate values$?
})
}
}
<value-display [values]="values$ | async"></value-display>
<button (click)="retryGetValues()">retry</button>
I have tried to create an event emitter to notify the template observable, but this did not cause a rerender of the template:
private notify = new EventEmitter()
public values$ = combineLatest([this.getValues(), this.notify.asObservable()]).pipe(map([first]) => first)
public retryGetValues() {
this.getValues().pipe(take(1)).subscribe(() => {
this.notify.emit()
}))
}
2
Answers
you can try this:
solution 2:
Make values signal:
in html:
To trigger the refresh I use a
BehaviorSubject
, which can emit values and since it has an initial value, the initial call is made.Then we take this
BehaviourSubject
and useswitchMap
to switch the observable to the API call that gives us the data for the list view.To get rid of the
async
pipe, I usetoSignal
, so that we can access the data directly.Finally we take this new signal and send the data to the child component in HTML.
Full Code:
Stackblitz Demo