Передача ошибок из Сервиса в Компонент - PullRequest
0 голосов
/ 23 февраля 2020

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

Это будет фиктивный пример. Это метод в Сервисе, который выдает ошибку.

public serviceMethod(value1: Class1): Observable<Interface1>{
    return new Observable(result => {
      this.method1(class1) // this method throws an error and returns an number 
        .subscribe(decimalValue  => this.method2(decimalValue) // this method does an error check and returns an Interface1 type
          .subscribe(value2 => this.method3(value2, result, decimalValue)), error1 => throwError(error1)
        )
    })
  }

Поскольку method1 выдает ошибку, error1 также будет выброшена. Теперь я хочу передать как-либо значение или ошибку из сервиса методу в другом Компоненте.

Вот как будет реализован метод в другом компоненте:

    public methodInTheComponent = async () =>{
    this.service.serviceMethod(valueOfClass1).subscribe(result => concole.log(result), error2 => console.log(error2));
  }

Теперь, когда я запускаю это, я просто получаю выходные данные с ошибкой1, но не с ошибкой2.

Причина этого заключается в том, что ошибка выдается из метода 1, и он не достиг других методов 2 и 3, чтобы вернуть результат ошибки.

Одно решение, о котором я подумал, это используя логическую переменную в сервисе. Например, errorThrown = true , а затем передать это компоненту. Тогда я мог бы выполнить проверку if в подписке.
Если errorThrown имеет значение true, error2 также должен быть выдан.

Я не уверен, что это хорошее решение! Одна проблема в том, что я не знаю, как отправить это errorThrown в Компонент!

Любое предложение или идея о том, что может быть возможным хорошим решением?

1 Ответ

1 голос
/ 23 февраля 2020

Inner Observables не будут работать, когда внешние из них выйдут из строя. Так что в вашем случае, если method1 выдает ошибку, он не будет выполнять method2 и method3. Но если вы хотите продолжить выполнение внутренних результатов, вы должны перехватить ошибки и вернуть их как нормальные значения для продолжения выполнения.

Измените свой класс обслуживания, как показано ниже, чтобы ловить и обрабатывать ошибки:

...
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class MyService {
  method1() {
    const obs;
    // perform your logic and store the Observable in obs object

    /**
    * catch the error and convert it to a normal observable
    * for execution of inner observable to continue
    */
    return obs.pipe(catchError(err => of(err)));
  }

  // implement method2 and method3 in similar fashion
  ...

  serviceMethod() {
    return this.method1().pipe(
      concatMap(val1 => {
        console.log('result of method1: ', val1);
        return this.method2();
      }),
      concatMap(val2 => {
        console.log('result of method2: ', val2);
        return this.method3();
      })
    );
  }
}

Обратите внимание, что я использовал оператор concatMap rx js для наблюдаемых, зависящих друг от друга, потому что создание вложенной подписки является анти-шаблоном и его не рекомендуется использовать. concatMap автоматически подпишет для вас внутренние наблюдаемые, так что не подписывайтесь на них вручную. Для получения дополнительной информации о concatMap, проверьте эту статью .

Теперь в вашем классе компонентов подпишитесь на serviceMethod из класса обслуживания, как показано ниже:

this.service.serviceMethod().subscribe(
  val => {
    console.log("End result: ", val);
  },
  err => {
    console.error("Error -> ", err);
  }
);

Теперь вы можете выполнять внутренние наблюдаемые, даже если внешние выдают ошибку. Полный пример приведен в этом проекте Stackblitz . Откройте консоль рендерера с правой стороны, чтобы просмотреть результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...