Вы должны отловить ошибку во внутреннем наблюдаемом конвейере вместо наблюдаемого источника. Если вы поймаете ошибку в источнике, наблюдаемом, то, согласно концепции rxjs, наблюдаемый источник не будет выдавать новые значения после возникновения ошибки. Так что лови ошибку во внутренней наблюдаемой так:
this.saved$ = saveClick$.pipe(
//i am assuming this.pushUser() is a higher order function which returns an observable
this.pushUser()
.pipe(
catchError(() => Observable.empty<AdministrationUser>())
),
share()
);
Поймав ошибку во внутренней наблюдаемой, ваш источник станет видимым живым и будет продолжать излучать значения, даже если ваша внутренняя наблюдаемая выдает ошибку.
Вы можете перемещать своего share()
оператора в соответствии с вашими потребностями [т.е. либо внутри вашей внутренней наблюдаемой, либо в наблюдаемой линии трубопровода источника], но идея остается той же - поймайте ошибку внутри внутренней наблюдаемой трубы, чтобы сохранить ваш источник (внешний) наблюдаемый живым.
РЕДАКТИРОВАТЬ 1: [Предлагая упрощенный код в соответствии с последним кодом пользователя]
Пожалуйста, определите ваш метод push в вашем сервисе так:
push(user) {
//By seeing your code; I could not figure out where and how are you passing the parameter in buildUrl
//It appears to me that this.buildPushURL method simply return an URL based on the passed parameters and IT DOES NOT MAKE
//ANY HTTP CALL TO YOUR BACKEND. IF THAT IS TRUE -
//THEN please adjust the below code accordingly as I dont know how you use this method OR PLEASE provide some more detaling
//on this.buildPushURL() method
const url = this.buildPushURL(filter.currentUser, filter.currentApplication, filter.userId);
//I am assuming that httpMethodFn calls http.get() or http.post() and returns an observable
//Suggestion - Why you dont use httpClient.get or httpClient.post() directly? It will avoid to call
//httpMethodFn by httpMethodFn.call?
//Bottom line is - httpMethodFn.call must return an observable otherwise adjust your httpMethodFn.call code to return an observable
//to make below code work.
return httpMethodFn.call(this.authHttp, url, user)
.pipe(
map(user => {
console.log(user);
return user;
}),
catchError(error => throwError(<ResponseError>error.json()))
);
}
И используйте это так -
yourMethodReturnsAnObservableWhichIsSubscribeByTheConsumer() {
const saveClick$ = Observable.fromEvent(this.saveButton.nativeElement, 'click');
return saveClick$.pipe(
switchMap(() => {
return this.push(user)
.pipe(
//you catch error here so that your outer observable will keep alive
//please adjust you code as per your need
//I guess it will give you an idea
handleError()
)
})
);
}
Надеюсь, вы получите представление о том, как упростить ваш код. Я не мог предоставить идеальное решение, так как я не знаю о вашем дизайне и полном коде. Я уверен, что приведенный выше код даст вам представление.
Предложение. Хорошо использовать функцию высшего порядка, но следует понимать, что не следует злоупотреблять ими, поскольку это затрудняет понимание вашего кода [PS - Это мое личное мнение, и хорошо иметь разные мнения. . :)]. Сделайте свою наблюдаемую цепочку максимально простой, применяя функциональный стиль кодирования. RXJS - это круто :)