Derek Liang
Derek Liang

Reputation: 1222

how to create a new observable subscription based on existing observable in rxjs?

I need to do something as the following line in my project(from https://github.com/devyumao/angular2-busy)

ngOnInit() {
    this.busy = this.http.get('...').subscribe();
}

In my project, I am making request based on route change as the following:

ngOnInit(): void {   
    this.activatedRoute
        .params
        .map(params => params['queryString'])
        .flatMap(id => this.http.(''))
        .subscribe(result => this.data = result);   
}

It seems I need to create a new subscription every time there is a change in route. I am not sure how to do it.

I am looking for rxjs solution only (without using Promise).

Thanks!

derek

Upvotes: 5

Views: 693

Answers (2)

Derek Liang
Derek Liang

Reputation: 1222

Actually, you can subscribe to the ajaxCallObservable in the chain. :)

ngOnInit(): void {   
    this.activatedRoute
        .params
        .map(params => params['queryString'])
        .map(id => this.http.(''))
        .do(ajaxCallObservable => { this.busy = ajaxCallObservable.subscribe() })
        .flatMap(ajaxCallObservable => ajaxCallObservable)
        .subscribe(result => this.data = result);   
}

Upvotes: 2

Thierry Templier
Thierry Templier

Reputation: 202326

I would globally (in your main component for example) register on route changes this way and trigger your request in the associated callback:

this.router.events
  .filter(event => event instanceof NavigationStart)
  // or NavigationEnd
  .subscribe(event => {
    this.http.post('').subscribe();
  });

This way you subscribe once on changes.

If you want to have access to route params, you need to inject the ActivateRoute instance as well and subscribe on its params attribute.

For this, I would leverage the combineLatest method of the Observable class, like described below:

export class AppComponent {

  constructor(private router: Router, private route: ActivatedRoute) {
    Observable.combineLatest(
      this.router.events
        .filter(event => event instanceof NavigationStart),
      this.route.params
    )
    .subscribe(data => {
      const event = data[0];
      const params = data[1];
      (...)
    });
  }
}

Don't forget to add this:

import 'rxjs/add/observable/combineLatest';

Upvotes: 4

Related Questions