0
votes

I cannot seem to figure out how to get my template to update. When I change a boolean property which is referenced in another array property, I would expect that my changes would change within the template. However, I am not seeing the changes.

When the app loads everything is loaded in its initial state (false: Login is visible and Logout is hidden), but when the isLogged boolean changes the navigation doesn't update to hide/show the correct item.

I think the issue is how Angular handles change detection on objects/arrays, but I am not sure.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  public isLogged: boolean = false;

  public navigation: INav = {
    links: [
      {
        text: 'Login'
        hidden: !this.isLogged
      },
      {
        text: 'Logout'
        hidden: this.isLogged
      }
    ]
  }

  public ngOnInit(): void {
    // Triggered whenever the login state changes
    this.authService.loginState().subscribe(state => {
      this.isLogged = state;
    });
  }

}
<third-party-nav [model]="navigation"></third-party-nav>
1
What does the third-party-nav component look like? - MikeOne
I don't know. I didn't code it. - Get Off My Lawn

1 Answers

0
votes

This problem is not related to angular's change detection. The problem in your code is that you set the navigation only once when the component is created (an therefore the variable isLogged is false). Instead you should update it when the loginState changes. You can do this by using observables/rxjs:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {


  public navigation: Observable<INav>;

  public ngOnInit(): void {
    // When the login state changes the navigation object also changes
    this.navigation = this.authService.loginState().map(s => ({
      links: [
        {
          text: 'Login',
          hidden: !s
        },
        {
          text: 'Logout',
          hidden: s
        }
      ]
    }));
  }
}

Then in your html you can use the async pipe to handle the observable

<third-party-nav [model]="navigation | async"></third-party-nav>