Search code examples
angularfirebaseionic-frameworkangularfire2

Angularfire undefined variable


Im try to get my current user storage on the realtime database from firebase using angularfire2

  public user: any;
  public userRef: any
  public currentUser: any;
  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    private fireAuth: AngularFireAuth,
    private userProvider: UserProvider,
    private fireDateBase: AngularFireDatabase
  ) {
    this.currentUser = this.fireAuth.auth.currentUser.uid;
    this.userRef = this.fireDateBase.object('CITYNAV_USERS/' + this.currentUser);
    this.getCurrentUser();
  }

  ionViewDidLoad() {
  }

  public getCurrentUser(): void {
    this.userRef.snapshotChanges().subscribe(action => {
      this.user = action.payload.val();
      console.log(this.user);
    });
  }

but for some reason when the this.user tell that is undefined and i have no idea why. Any idea.

HTML

<ion-content padding>
  <div class="wrapper-profile">
    <img src="assets/imgs/logo-f.png" alt="">
    <div class="wrapper-avatar">
      <div class="avatar">
        <img src="{{user.avatar}}" alt="avatar">
      </div>
      <button ion-button color="icons-color" clear>Cambiar imagen</button>
    </div>
  </div>
  <div class="wrapper-profile-form">
    <ion-item>
      <ion-label>
        <ion-icon name="ios-person-outline"></ion-icon> Nombre</ion-label>
      <ion-input clearInput type="text" [(ngModel)]="user.name"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>
        <ion-icon name="ios-mail-outline"></ion-icon> Email</ion-label>
      <ion-input clearInput type="email" [(ngModel)]="user.email"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>
        <ion-icon name="ios-lock-outline"></ion-icon> Password</ion-label>
      <ion-input clearInput type="password" [(ngModel)]="user.password"></ion-input>
    </ion-item>
    <div class="profile-btn">
      <button class="btn-edit" ion-button color="secondary" round>Editar informacion</button>
      <button class="btn-logout" ion-button color="secondary" (click)="logOut()" round>Log Oout</button>
    </div>
  </div>
</ion-content>

Here is the html to render the user object after get it from the realtime database.

console log the response object

    Object { 
      avatar: "assets/imgs/avatar.jpg", 
      created: "Wed Nov 08 2017 16:54:53 GMT+0100", 
      email: "mianfrigo@gmail.com", 
      password: "Atenas10", 
      rol: "user", 
      userName: "Miguel Frias" 
    }

Solution

  • Now when you have made the appropriate changes to place your console log inside the callback (subscribe)...

    You can initialize your user or use *ngIf in your template, as the data is coming async, view is rendered before data has arrived. Or you can use the safe navigation operator, safe navigation operator does not work with two-way-binding though, so you'd need to split that to one-way-binding and ngModelChange:

    <input [ngModel]="user?.name" (ngModelChange)="user.name = $event"/>
    

    or as mentioned, you could use ngIf and wrap your template in a div like:

    <div *ngIf="user">
      <!-- code here-->
    </div>
    

    or maybe the easiest solution is to just initialize the object. This will work if you do not have nested objects inside your object. So just initialize your user:

    user = {};