Search code examples
angulartypescriptangular2-directives

Preserving Angular component variables while using *ngIf


Below is my very slimmed down code.


app.component.html

<app-nav></app-nav>
<app-login *ngIf="!loggedIn"></app-login>

app.component.ts

  loggedIn: boolean;
  ...
  //Shared service login logic - this stuff works
  loggedIn = true;
  loggedIn = false;

login.component.ts

  email: string;
  pass: string;

  Login(){
    //Shared service login logic - passes in this.email and this.pass
    //unset password but keep email
  }

login.component.html

<input type="email" required [(ngModel)]="email" />
<input type="password" required [(ngModel)]="pass" />
<button type="submit"  (click)="Login()">Sign In</button>

My code works great and mostly as intended. When a user is not logged in, the <app-login> component is not visible and vice versa. However, it is my intent to only unset the password in the login.component.ts since the email <input> is bound to email using ngModel I would think that it would be retained.

However, when a model is deconstructed and removed from the DOM, it seems that all the local variables are unset as well. What can I do to prevent this?


Solution

  • There are many ways to do this. You could have store the email in your app.component, use local storage or a shared service.

    • Get the data from the parent component ( your app.component )

    app.component.html

        <app-nav></app-nav>
        <app-login [email]="email" *ngIf="!loggedIn"></app-login>
    

    app.component.ts

      loggedIn: boolean;
      ...
      //Shared service login logic - this stuff works
      loggedIn = true;
      loggedIn = false;
      //new variable
      email = ""
    

    and in your login.component, add @Input into your code to get the email from the app.component.

    @Input email;
    
    • Local storage

    Whenever you login, save the email in your local storage like this

     Login(){
          localStorage.setItem('email', email);
          // your login code
      }
    

    and retrieve it later via constructor when you create the login.component again.

    constructor(){
       this.email = localStorage.getItem('email');
    }
    
    • Shared service

    The implementation is almost identical when using local storage, you need to set the email when you log in and retrieve it again when you create the login component again. Just make sure that you provide it in your app.module to make it a singleton.

    Hope this helps