Search code examples
angularangular-httpclientangular-observable

Why the code segment is creating memory leak?


I am using http service to get user data from UserService. When i am subsscribing to the observable it is creating a memory leak. In the network tab of developer console it is visible that infinite http requests are being made.

tried to unsubscribe in ngOnDestroy() method, but no luck.

user.service.ts

getCurrentUserDetails(){
    return this.http.get<User>(`${this.config.apiUrl}/user/me`);
  }

navbar.component.ts

export class NavbarComponent implements OnInit, OnDestroy {

  user: User;
  userDetailsSubs: Subscription;
  constructor(
    private router: Router,
    private authenticationService: AuthenticationService,
    private userService: UserService
  ) { }

  ngOnInit() {
  }
  isLoggedIn() {
    const currentUser: User = this.authenticationService.currentUserValue;
    if (currentUser) {
      this.userDetailsSubs = this.userService.getCurrentUserDetails()
        .subscribe(
          data => {
            this.user = data;
          }
          , error => {
            console.log(error);
          });
      //this.userDetailsSubs.unsubscribe();
      return true;
    }
    else
      return false;
  }
  logout() {
    this.authenticationService.logout();
    this.router.navigate(['/login']);
  }
  ngOnDestroy() {
    this.userDetailsSubs.unsubscribe();
  }
}


navbar.component.html

<div class="sticky-top mb-3">
  <nav class="navbar navbar-expand-lg navbar-dark bg-danger justify-content-center p-3 mb-3" *ngIf="!isLoggedIn()">
    ..............
  </nav>
  <nav class="navbar navbar-expand navbar-dark bg-danger p-3 mb-5" *ngIf="isLoggedIn()">
      .
      .
      .
  </nav>
</div>


Solution

  • Your isLoggedIn() function is triggered from template on change detection. Add isLogged property to your component and set it from ngOnInit to avoid multiple calls.

    isLogged: boolean;
    
    ngOnInit() {
      const currentUser: User = this.authenticationService.currentUserValue;
        if (currentUser) {
          this.userDetailsSubs = this.userService.getCurrentUserDetails()
            .subscribe(
              data => {
                this.isLogged = true;
                this.user = data;
              }
              , error => {
                console.log(error);
              });
        }
        else
          this.isLogged = false;
    }