Каким-то образом catchError http-запроса не работает с помощью cordova - PullRequest
1 голос
/ 06 апреля 2020

Итак, вчера я разрабатывал какую-то автономную функциональность. Поэтому я добавил ApiService, который возвращает Observables. В настоящее время я получаю свой access_token для jwt-Authentication, а затем использую этот токен для генерации заголовков для моего API-запроса. После успешного запроса я сохраняю результат в своем хранилище. Это отлично работает. Теперь вот проблема, которую я хочу проверить на неудачный запрос (например, серверы не работают, приложение отключено), а затем вернуть сохраненный результат из хранилища. Но я не могу заставить его работать.

Вот мой код:

  getJobs(): Observable<any> {
    this.auth.checkToken()
    return from(this.storage.get(ACCESS_TOKEN)).pipe(
      switchMap(token => {
        let options = this.auth.addToken(token)
        return this.http.get(API_URL + "jobs", options)
      }),
      map(res => {
          if (res) {
            this.storage.set(JOBS, res)
            return res
          } else {
            return from(this.storage.get(JOBS))
          }
      }),
      catchError(() => {
        return from(this.storage.get(JOBS))
      })
    )
  }

Дальнейшие исследования показали, что после отключения сервера или приложения ни map (), ни Функции catchError () были выполнены.

ОБНОВЛЕНИЕ: Решение, предоставленное DJ House, является правильным. Мой код прекрасно работает в моем браузере, но если я создаю свое приложение с ionic cordova build android, оно застревает после this.http.get(...) Так что это ясно и проблема с cordova

РЕШЕНИЕ: Ух ты! Произошло что-то волшебное! Я обнаружил, что метод catchError вызывается НО почти через 2 минуты, что очень медленно ... Итак, я реализую время ожидания.

Спасибо flixoflax

Ответы [ 2 ]

0 голосов
/ 06 апреля 2020

Основная проблема, с которой вы можете столкнуться, это неправильное использование map. Карта действует на нормальное значение (обычно это не наблюдаемое) и возвращает новое значение. map() всегда должен возвращать один и тот же тип значения. В вашем map() вы либо возвращаете ответ (который, я предполагаю, имеет тип Jobs) ИЛИ , вы возвращаете Observable<Jobs>. Это заставит ваших подписчиков нуждаться в подробных логах c, чтобы справиться с этим.

Похоже, вы пытаетесь использовать это map() для установки локального хранилища с возвращенными заданиями из вашего API. Я бы рекомендовал использовать tap(), поскольку вы не пытаетесь изменить возвращаемое значение.

function getJobs(): Observable<any> {
  this.auth.checkToken()
  return from(this.storage.get(ACCESS_TOKEN)).pipe(
    switchMap(token => {
      let options = this.auth.addToken(token)
      return this.http.get(API_URL + "jobs", options)
    }),
    // change to tap()
    tap(res => {
      if (res) {
        this.storage.set(JOBS, res)
      }
    }),
    catchError(() => {
      return from(this.storage.get(JOBS))
    })
  )
}

Если switchMap выдает ошибку, нажатие будет пропущено. Это позволит вам установить хранилище , только если вы получите значение из API. Если вы всегда хотите установить хранилище (даже если API выдает ошибку), тогда переместите tap() на после на catchError().

0 голосов
/ 06 апреля 2020

Можете ли вы попробовать переместить оператор catchError в качестве первого оператора внутри метода pipe. Это сделано для того, чтобы вы поймали ошибку, как только получите ее от наблюдаемой. Пожалуйста, измените его, как показано ниже:

  getJobs(): Observable<any> {
    this.auth.checkToken()
    return from(this.storage.get(ACCESS_TOKEN)).pipe(
      switchMap(token => {
        let options = this.auth.addToken(token)
        return this.http.get(API_URL + "jobs", options)
      }),
      catchError(() => {
        return from(this.storage.get(JOBS))
      })
      map(res => {
          if (res) {
            this.storage.set(JOBS, res)
            return res
          } else {
            return from(this.storage.get(JOBS))
          }
      }),
    )
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...