Оператор fromEvent не запускается после «Элемент не найден результат поиска» - PullRequest
1 голос
/ 07 июля 2019
  1. Я ищу предмет
  2. Если предмет не найден (404), я получаю сообщение об ошибке, как и ожидалось
  3. Снова, если я пытаюсь найти новый предмет, fromEvent вообще не сработает

Не уверен, почему это так?

fromEvent(this.searchInput.nativeElement, 'keyup').pipe(
    tap(() => console.log('qorking')),
    map((event: any) => {
      if (event.keyCode === 17 || event.keyCode === 91 || event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40 || event.keyCode === 13 || event.keyCode === 27) {
        return;
      }
      return event.target.value;
    }),
    filter((query: any) => {
      if (!this.loading && (!query || query == '')) {
        this.searchedResult = [];
        return false;
      }
      return true;
    })
    , debounceTime(275)
    , distinctUntilChanged() // If previous query is different from current
    , switchMap(query => {
      if (query && query !== '') {
        query = query.trim();
        this.loading = true;
        return this.cartService.searchItemByName(encodeURIComponent(query), this.shopID.shop_id.toString());
      } else {
        this.searchedResult = [];
        this.loading = false;
        return EMPTY;
      }
    }),
    // subscription for response
).subscribe((res: any) => {
  this.searchedResult = [];
  let data = res.result;
  console.log('res', data);
  this.searchedResult = data;
  this.loading = false;
  if (data.length) this.setSelectedItem(data[0], 0);
}, (err) => {
  console.log('error', err);
  this.loading = false;
  this.searchedResult = [];
  this.toaster.error(err.error.message || "Something went wrong!");
})

Ответы [ 2 ]

0 голосов
/ 07 июля 2019

Как вы упомянули, в случае 404 ваш обратный вызов ошибки вызывается так, ваш код работает так, как ожидал наблюдаемый дизайн.Согласно схеме Observable, если ошибка (исключение) возникает в наблюдаемом конвейере, тогда наблюдаемая находится в состоянии ошибки и не может выдавать новые значения (https://blog.angular -university.io / rxjs-error-processing / ) и его можно считать завершенным [то есть он не может выдавать новые значения].По этой причине событие keyup не запускается после возникновения ошибки.

Теперь, чтобы сохранить наблюдаемый источник в реальном времени в случае ошибки (в вашем случае событие keyup продолжает вызываться в случае ошибки)обработайте ошибку в наблюдаемой, которая выдает ошибку, используя оператор catchError.В вашем случае this.cartService.searchItemByNam метод, который возвращает наблюдаемый.Итак, давайте изменим ваш код следующим образом:

fromEvent(this.searchInput.nativeElement, 'keyup').pipe(
    tap(() => console.log('qorking')),
    map((event: any) => {
      if (event.keyCode === 17 || event.keyCode === 91 || event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40 || event.keyCode === 13 || event.keyCode === 27) {
        return;
      }
      return event.target.value;
    }),
    filter((query: any) => {
      if (!this.loading && (!query || query == '')) {
        this.searchedResult = [];
        return false;
      }
      return true;
    })
    , debounceTime(275)
    , distinctUntilChanged() // If previous query is different from current
    , switchMap(query => {
      if (query && query !== '') {
        query = query.trim();
        this.loading = true;
        return this.cartService.searchItemByName(encodeURIComponent(query), this.shopID.shop_id.toString())
.pipe(
  catchError(err => {
    console.log('error', err);
          this.toaster.error(err.error.message || "Something went wrong!");
          //in case of error let’s emit an empty array like you doing in other else conditions
          return of([]):
  })
);
      } else {
        this.searchedResult = [];
        this.loading = false;
        return EMPTY;
      }
    }),
    // subscription for response
).subscribe((res: any) => {
  this.searchedResult = [];
  let data = res.result;
  console.log('res', data);
  this.searchedResult = data;
  this.loading = false;
  if (data.length) this.setSelectedItem(data[0], 0);
}, (err) => {
  console.log('error', err);
  this.loading = false;
  this.searchedResult = [];
  this.toaster.error(err.error.message || "Something went wrong!");
})

Надеюсь, это поможет.

Кстати, ваш код имеет множество возможностей для улучшения.

0 голосов
/ 07 июля 2019

Я вижу, что вы вызываете методы на this внутри функций, которые вы передаете операторам этой наблюдаемой, что означает, что есть побочные эффекты, вызванные, когда эта наблюдаемая испускает события.

У меня нет полного контекста о том, как этот код изменяет состояние мира, но одна возможность состоит в том, что элемент, на который вы подписываетесь на события keyup, больше не находится на странице послепроисходит начальное 404.

Возможно, это не вызовет ошибки, поскольку наблюдаемое просто подписано на неправильный элемент.Но мне нужно больше знать об окружающем контексте, чтобы сказать это с уверенностью.

...