Angular - Handle multiple subscriptions inside a pipe of another servicemethod

179 Views Asked by At

I'm working on an Angular app with REST API - Java Spring Boot for the backend side, and we need to implement a pooling mechanism for long running queries.

The High-level diagram

I want to implement this at the service level, not for each component.

Make the httpCall.put

  • if status 200 return body

  • if status 202 display confirmation popup

    -> if user cancels -> STOP

    -> if user continues -> start polling mechanism

         - polling mechanism meaning calling http.get('api/reqId/status',reqId) - while status is 200
         - end when status 201 and call http.get('api/reqId/result', reqId)
    

Within the component.ts we have a method (componentMethod) that calls the service method.

componentMehod(param): {
serviceMethod(param).subscribe(response => {
       // some logic
});
}

In the service we have the


constructor(private http:HttpCLient, private pollingDialogService: PollingDialogService)

serviceMehod(param): Observable<Model> {
      return this.http.put(url,param, {observe: 'response'}).pipe(
    map((response) => {
    if (response.status === 200) {
                 return <Model> response.body;
                 }
    if (response.status === 202) { 
        // display confirmation popup - cancel/continue
      this.pollingDialogService.showPollingDialog = true;
      this.pollingDialogService.startPolling$.subscribe(response => {
                       if (response) {// if the user clicks continue - start polling
                        this.getRequestStatus(reqId).subscribe(response => {
                                       this.getRequestResults(reqId).subscribe(response => {
                                                   return response;
                                                       })
                                             })
                                      }
          }
    })
}



getRequestStatus(reqId: string): Observable<any> {
    return timer(0, 1000).pipe( 
        switchMap(() => this._http.get(pollingUrl, {observe: 'response'})),
        //stop polling when status will be 201
        takeWhile((response: HttpResponse<any>) => response.status === 200, true), 
        takeLast(1),
        map((response: HttpResponse<any>) => {
          return response;
        }),
    );
  }



getRequestResults(reqId: string): Observable<Model> {
    return this._http.get(reqResultsUrl).pipe(
        map((response) => {
          return <Model>(response);
        }));
  }


The problems are:

  • that the component gets the result before everything thats's in this.pollingDialogService.startPolling$.subscribe block to be completed
  • nested observables in serviceMehod which are no good :(

Thank you for your time and patience to read this long post. This is the first time I'm posting so I hope I provided useful details so you can help me :)

0

There are 0 best solutions below