1
votes

I have a angular 4 app. In this app I have a paypal service, which does some server work and navigates (from client) to paypal.

 
@Injectable()
export class PaypalService {
  private readonly http: HttpApi;

  constructor(private readonly httpFactory: HttpFactoryService) { 
    this.http = httpFactory.get(HttpRequestType.Secured);
  }

  checkout(transactionId: string):
   Observable<Response> {
    let subscriber = this.http.post(environment.paymentServer + '/pay', {transactionId: transactionId})
    subscriber.subscribe((response:Response) => {
        let result = response.json();
        window.location.href = result.paymentUrl;
    });
    return subscriber;
  }
}

I want the window.location.href will be called only after all subscribers was notified.

paypal.checkout("1234").subscribe(() =>
//This code should be called before the navigation will start
doSomeCleaning())

I know I can use delay, but I was wondering if there is a better option.

2
Try to map all streams with flatMap operator for example and at end to have only one subscribe method from which you can call the redirect. - Yordan Nikolov

2 Answers

0
votes

Since you need to force the observers to be called in specific order you shouldn't rely on their order of subscriptions. The easiest way is to use setTimeout() without any delay:

observable.subscribe((response:Response) => {
    let result = response.json();
    setTimeout(() => window.location.href = result.paymentUrl);
});

Or maybe a better and more Rx way could be using observeOn operator and the async Scheduler to emit the value to the first observer in another JS event.

import { async } from 'rxjs/scheduler/async';

...

let observable = ...
observable.observeOn(async).subscribe(...);

return observable;
0
votes

Why don't you do redirect in callback as following:

paypal.checkout("1234").subscribe((res) =>{
   doSomeCleaning();
   window.location.href = res.paymentUrl; 
});