问题
Seems like pipe doesn't work with reactive form control valueChanges. i've prepared this https://stackblitz.com/edit/angular-vdeqrz so that you can reproduce the problem.
type something in the text field. then type "boom" (without the quotes). after the error catch, the control does not work any more. you can verify typing something new on it after that. it does not detect any other input.
if you refresh the page, then it works again.
am i missing something here ?
回答1:
This is not a bug. Every Rx stream can emit zero or more next notifications and one error or complete notification but never both.
So if you use throwError the chain will dispose itself because you can never have the same chain emitting two or more error notification which is what you expect.
There're obviously many ways to avoid this. You can use something different than throwError and wrap the input value with some object for example. But then you won't be able to handle it in observer's error handler.
You can also use retry and tap to handle the error:
this.query.valueChanges
.pipe(
switchMap(d => (d === 'boom') ? throwError(new Error("boom")) : of(d)),
tap({ error: err => console.log(err) }),
retry(),
)
.subscribe({
next: d => console.log(d),
complete: () => console.log("complete")
})
You'd have to use tap here because the error never reaches the observers.
Your updated demo: https://stackblitz.com/edit/angular-1qfn2z?file=src/app/app.component.ts
回答2:
Yeah you're definitely missing something.
Open your console (the browser one, not the blitz one) and see that you actually have an error :
Error: boom
at SwitchMapSubscriber.eval [as project] (app.component.ts:43)
at SwitchMapSubscriber._next (switchMap.ts:100)
at SwitchMapSubscriber.Subscriber.next (Subscriber.ts:102)
at SafeSubscriber.schedulerFn [as _next] (event_emitter.ts:88)
at SafeSubscriber.__tryOrUnsub (Subscriber.ts:270)
at SafeSubscriber.next (Subscriber.ts:212)
at Subscriber._next (Subscriber.ts:142)
at Subscriber.next (Subscriber.ts:102)
at EventEmitter.Subject.next (Subject.ts:62)
at EventEmitter.emit (event_emitter.ts:78)
This is what is messing with your application.
回答3:
rxjs throw error operator will stop the observable from emitting again just like you have unsubscribe from the valueChanges observable
try like this intand of using throwError operator just throw new Error object
this.query.valueChanges
.pipe(map(d => (d === 'boom') ? new Error("boom") : d))
.subscribe(
d => console.log(d),
err => console.log(err),
() => console.log("complete")
)
来源:https://stackoverflow.com/questions/51650890/angular-reactive-form-valuechanges-with-pipe-is-this-a-bug