问题
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