Search code examples
angularrxjsrxjs-pipeable-operators

Create generic type on const angular


I'm having problems with error handlers. I'm trying to create a generic retryPipeline in my service: when the call fails, it retry 3 times before throw and error. So far so good. It works if I put the code inside the method, like this :

  getMun(id_del: number, id_muno: number): Observable<Mun> {

    let urlAPIMun = urlAPI;
    urlAPIMun += '/' + id_del + '/mun' + '/' + id_mun + '?flag_geometry=true';
    return this._http.get<Mun>(urlAPIMunicipios).pipe(
     //   tap(() => console.log('HTTP request executed')),
      retryWhen(errors => errors.pipe(
        // Concat map to keep the errors in order and make sure they
        // aren't executed in parallel
        concatMap((e: HttpErrorResponse, i) =>
          // Executes a conditional Observable depending on the result
          // of the first argument
          iif(
            () => i >= 3,
            // If the condition is true we throw the error (the last error)
            throwError(e.error.errores),
            // Otherwise we pipe this back into our stream and delay the retry
            of(e).pipe(delay(5000))
          )
        ))));
  }

I'm trying to extrac the code inside pipe to declare a const and then call the const in my service call:

const RETRYPIPELINE =
  retryWhen((errors) =>
    errors.pipe(
      concatMap((e: HttpErrorResponse, i) =>
          () => i >= 3,
          throwError(e.error.errores),
          of(e).pipe(delay(5000))
        )
      )
    )
  );

return this._http.get<Mun>(urlAPIMunicipios).pipe(RETRYPIPELINE);

But I'm receiving this error:

error TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. Type '{}' is missing the following properties from type 'Mun': id_mun, id_del, den

Is there any way to create a generic const, that can be able to asign to any method, although the method returns a typed value? Thanks in advance


Solution

  • Finally, I fixed it thank to this answer :

    Adding a cast in retryWhen, definitively solve my problem:

    export const RETRYPIPELINE =
      retryWhen<any>((errors) =>
        errors.pipe(
          // Use concat map to keep the errors in order and make sure they
          // aren't executed in parallel
          concatMap((e: HttpErrorResponse, i) =>
            // Executes a conditional Observable depending on the result
            // of the first argument
            iif(
              () => i >= 3,
              // If the condition is true we throw the error (the last error)
              throwError(e.error.errores),
              // Otherwise we pipe this back into our stream and delay the retry
              of(e).pipe(delay(5000))
            )
          )
        )
      )
    

    ;