gsiradze
gsiradze

Reputation: 4733

router subscribe calls multiple time

With this code

ngOnInit() {
  this.router.events.subscribe((val) => {
    if (this.router.url.indexOf('page') > -1) {
      let id = this.activedRoute.snapshot.params['Id']
      this.busy = this.httpCall.get('/pub/page/GetPageById/' + id)
        .subscribe(data => {
          this.pages = <Page[]>data
        })

      console.log(id)
    }
  })
}

when I navigate to domain.com/#/en/page/13 it logs 13 as expected.

But when I navigate to the page which id is 27 it logs: 13 13 27.

When I navigate back to 13 log has: 27 27 13.

Why is it?

Upvotes: 15

Views: 15913

Answers (5)

ssomu
ssomu

Reputation: 89

I have faced the same problem . I could able to resolve by maintaining a flag

ngOnInit() {
        this.router.events.filter(event => event instanceof 
        NavigationEnd).subscribe(() => {
        let render = false;
        if(this.router.url.indexOf('page') > -1 && !render){
        //here goes logic 
        render = true;
      }
    }
  }**

Upvotes: 0

Ricardo Ramirez M
Ricardo Ramirez M

Reputation: 1

Step 1:

_routerSub = Subscription.EMPTY;

Step 2:

ngOnInit(){

    this._routerSub = this.router.events
        .pipe(filter((event: RouterEvent) => event instanceof NavigationEnd))
        .subscribe(() => {
            this.getPosts(this.activatedRoute.snapshot.params.cattmpd);
         });
}

ngOnDestroy(): {

    this._routerSub.unsubscribe()

}

Upvotes: 0

Iman Fattahi
Iman Fattahi

Reputation: 21

This happens when you write "this.router.events" on ngOnInit or Constructor, For fixing this issue you should write it on other function like that:

onRouteChange () {
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationStart) {
        if (this.router.url.indexOf('page') > -1) {
            let Id = this.activedRoute.snapshot.params['Id'];
            this.busy = this.httpCall.get('/pub/page/GetPageById/' + Id)
                .subscribe(
                data => {
                    this.pages = <Page[]>data;
                });

            console.log(Id);    
        }
      }
    })
  }

but there is another issue in this which you should consider when you use "this.router.events.subscribe", everything you wrote down in this function happens when you navigate in pages so it better to use this line to prevent run it on every path changes:

import {Router, NavigationStart} from '@angular/router';

onRouteChange () {
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationStart) {
        // this line
        if(event.url == 'your_page_path')
        if (this.router.url.indexOf('page') > -1) {
            let Id = this.activedRoute.snapshot.params['Id'];
            this.busy = this.httpCall.get('/pub/page/GetPageById/' + Id)
                .subscribe(
                data => {
                    this.pages = <Page[]>data;
                });

            console.log(Id);    
        }
      }
    })
  }

Upvotes: 0

Nikolai
Nikolai

Reputation: 489

From your logs you can see that your subscription is called three times on each route change. So that means events observable emits many signals but you interested in only one.

 ngOnInit() {
        this.getData();
        this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event =>  this.getData());    
  }
  getData(){
        if (this.router.url.indexOf('page') > -1) {
            let Id = this.activedRoute.snapshot.params['Id'];
            this.busy = this.httpCall.get('/pub/page/GetPageById/' + Id)
                     .subscribe(
                            data => {
                                this.pages = <Page[]>data;
                            });

             console.log(Id);
        }
    }

Upvotes: 10

user4676340
user4676340

Reputation:

You have to unsubscribe when you destroy your component.

First you have to

import { OnDestroy } from '@angular/core;'

Then you have to

export class myClass implements OnInit, OnDestroy {
    myObserver = null;
    // Rest of your code
}

In your ngOnInit, you have to

ngOnInit() {
    this.myObserver = this.router.events.subscribe(...);
}

Then, create a function

ngOnDestroy() {
    this.myObserver.unsubscribe();
}

Upvotes: 16

Related Questions