Angular 2 Subject.next не работает после того, как Observable его прослушивает, выдает ошибку

Я поражен сценарием, в котором у меня есть класс обслуживания Angular (WeatherService), который выполняет вызов REST для внешнего API и извлекает данные в функции searchWeather().

У меня есть компонент WeatherSearchComponent, который имеет поиск поля ввода в своем шаблоне, который имеет событие keyup, привязанное к функции onSearch() в компоненте. Это в основном поле ввода TypeAhead. У меня есть Subject, определенный в классе, и в функции onSearch() я инициализирую функцию next() субъекта, как показано ниже.

WeatherSearchComponent:

private searchStream = new Subject<string>();
onSearch(cityName:string) {
        this.searchStream
            .next(cityName);
    }

constructor(private _weatherService:WeatherService) {
    }

ngOnInit() {
        this.searchStream
            .debounceTime(300)
            .distinctUntilChanged()
            .switchMap((input:string) => this._weatherService.searchWeatherData(input))
            .subscribe(
              data => this.data = data
            );
    }

WeatherService:

searchWeatherData(cityName: string): Observable<any> {
        return this._http.get('URL')
            .map(response => response.json())
            .catch(error => {
                console.error(error);
                return Observable.throw(error.json())
            });
    }

Проблема, с которой я сталкиваюсь, заключается в том, что если вызов REST завершается неудачно или возвращает ошибку, я регистрирую ее, но жизненный цикл Subject searchStream заканчивается, как только он получает ошибку и после этого не принимает входные данные. Я попытался обработать ошибку в методе ngOnInit(), но он не работает.

Я хотел бы знать, как справиться с этим сценарием?

1 ответ

Решение

Это не проблема с Subject, Это общее поведение Rx. При отправке уведомления об ошибке цепочка удаляется.

Вы уже используете .catch() так что вы можете просто изменить его обратный вызов, чтобы не выбрасывать ошибку, а подавлять ее или что угодно:

.catch(error => {
    console.error(error);
    return Observable.empty()
});

Кстати, у субъектов действительно есть внутреннее состояние, о котором вы должны знать, но в вашем случае использования ошибка не достигает субъекта.

Другие вопросы по тегам