0

I'm new in Firebase and Typrescript. I have the following problem: I want the username of a user from the realtime database.

  getUsername(id){
    var username
    firebase.database().ref().child("users/"+id+"/username")
    .once("value",snapshot => {
      if (snapshot.exists()){
        username = snapshot.val();
        console.log("IN"+username)      
      }
    });
    console.log("OUT"+username)
    return username
  }

The problem is that outside the if() the username is undefined. I read that with firebase you have to work asynchronously, so I followed this guide: How do I return a snapshot.val() from Firebase to a variable? so I created the functions:

   getListings(id) {
    return firebase.database().ref().child("users/"+id+"/username").once("value");
  }
  
   loadListing(id){
    this.getListings(id).then(this. setListing, this.showError);
}

   setListing(snapshot){
      this.currentSnapshot = snapshot.val()
  }
  
   showError(e){
      console.log(e);
  }
  
   init(id){
      this.loadListing(id);
  }

and in other page I call init:

export class ProfilePage implements OnInit {
  username : any;
  constructor(private route: ActivatedRoute, private router: Router, public authService: AuthenticationService) {};
  
  ngOnInit() {
    this.authService.init(this.authService.userData.uid)
    console.log(this.authService.currentSnapshot)
  }
}

but i receive the error:

Error: Uncaught (in promise): TypeError: Cannot set property 'currentSnapshot' of undefined

Can anyone help me ?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
ChrisCv
  • 17
  • 7

1 Answers1

1

I suspect that the this in your setListing function is no longer referring to the object you expect.

If that is the cause, you might be able to fix it by binding it to the correct object:

this.getListings(id).then(this.setListing.bind(this));
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I tried with your comment. Now I don't have the error "Error: Uncaught (in promise): TypeError: Cannot set property 'currentSnapshot' of undefined" . But the line console.log(this.authService.currentSnapshot) returns "undefined" – ChrisCv Apr 07 '21 at 16:42
  • Yeah, that's my main concern with the entire code: you're not dealing with the fact the the data is loaded asynchronously consistently. You need to return a promise consistently, consuming the `then()` once doesn't mean the rest of the code can access the values from the database synchronously. My expectation is that `console.log(this.authService.currentSnapshot)` runs before `this.currentSnapshot = snapshot.val()` is executed. Running the code in a debugger (or adding some logging) con confirm that, and bring it back to https://stackoverflow.com/q/40688268 – Frank van Puffelen Apr 07 '21 at 17:17