0

I am learning Angular. I am trying to achieve, after the logged in the page redirect to homepage. Following I have tried,

app.component.html

<header *ngIf='loggedIn'>
<h1>Test portal</h1>
</header>
<login *ngIf='!loggedIn' (homeVar)="loadHome()">Loading..</login>

<router-outlet></router-outlet>

app.component.ts

export class AppComponent implements OnInit {
  loggedIn = 0;
  constructor(private router:Router){}
  ngOnInit(){
    if(!this.loggedIn){
      this.router.navigate(['']);
    }

  }
    loadHome():void{
      this.loggedIn=1;
      this.router.navigate(['home']);

  }

}

login.component.ts

export class loginComponent implements OnInit  {
    @Output() homeVar:EventEmitter<string> = new EventEmitter();

    @SessionStorage() session:any = "";

    ngOnInit(){
        if(this.session != ""){
            this.homeVar.emit(this.session);
        }
    }
   check(){
      this.session = "user";
   }
 }

The above code is working fine but it is giving the following error

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: 0'. Current value: 'ngIf: 1'.

How to fix this problem?

mkHun
  • 5,891
  • 8
  • 38
  • 85

3 Answers3

1

Instead of emitting event inside onInit use constructor

export class loginComponent {
    @Output() homeVar:EventEmitter<string> = new EventEmitter();

    @SessionStorage() session:any = "";

    constructor(){
        if(this.session != ""){
            this.homeVar.emit(this.session);
        }
    }
   check(){
      this.session = "user";
   }
 }

https://stackoverflow.com/a/48216423/2742156

Pratap A.K
  • 4,337
  • 11
  • 42
  • 79
  • I checked inside the constructor also but it is not emiting the response. – mkHun Sep 05 '18 at 07:10
  • If it's not emitting then u need to check if(this.session != "") this statement. My answer is to resolve the error ExpressionChangedAfterItHasBeenCheckedError – Pratap A.K Sep 05 '18 at 07:38
0

Try the below code in login.component.ts:-

ngOnInit(){
  if(this.session != null){

    // add setTimeout
    setTimeout(()=> {
      this.homeVar.emit(this.session);
    }, 0);

  }
}
Ankit Sharma
  • 1,674
  • 8
  • 11
  • Yes. Thanks it is working. Can you explain what is the reason.? why we have to make the setTimeOut with 0 mili sec? – mkHun Sep 05 '18 at 05:32
  • @mkHun - This is due to the change detection mechanism which is like a tree structure checking from the top to bottom for changes. But once your `loggedIn` was checked, it was again updated in the same cycle in your other component. Hence, we used `setTimeout` to start a new cycle again. – Ankit Sharma Sep 05 '18 at 05:34
0

@mkHun why don't you try to change the variable loggedIn to boolean this may helps you.

export class AppComponent implements OnInit {
  loggedIn :boolean = false;
  constructor(private router:Router){}
  ngOnInit(){
    if(!this.loggedIn){
      this.router.navigate(['']);
    }

  }
    loadHome():void{
      this.loggedIn = true;
      this.router.navigate(['home']);

  }

}
Ganesh
  • 5,808
  • 2
  • 21
  • 41
  • I have change the code 0 to Boolean but still this is not working – mkHun Sep 05 '18 at 05:31
  • refer this link which was answered https://stackoverflow.com/questions/43375532/expressionchangedafterithasbeencheckederror-explained – Ganesh Sep 05 '18 at 05:36