Ionic 2 - Sidemenu, View, Firebase Promise


#1

Hello everyone.

As a student, I’m currently stuck with trying to create the following:

I have in my sidemenu (based on the sidemenu template) a profilepicture & displayname that I want to swap with data from my firebase database.

I have the following code:

  1. App.html
        <img id="profile-image" src="assets/profile/{{ photoURL }}" alt="{{ displayName }}"/>
        <div id="profile-name" text-center class="width-full">{{ displayName }}</div>
  1. App.component.ts

var displayName;
var photoURL;
...
export class MyApp
{
constructor(..)
  {
    ..
    this.setUserData();
    ..
  }

  //SET USER
  setUserData()
  {
    this.uid = firebase.auth().currentUser.uid;

    console.log("UID: "+ this.uid);

    let ref = firebase.database().ref('/userProfile').child(this.uid);

    ref.once('value', function(snapshot)
    {
      //CALLBACK
      var key = snapshot.key;
      var em = snapshot.child("/email").val();
      var nm = snapshot.child("/name").val();
      var dpn = snapshot.child("/displayName").val();
      var pURL = snapshot.child("/photoURL").val();

      //LOG
      console.log("KEY: "+key);
      console.log("NAME: "+nm);
      console.log("DISPLAYNAME: "+dpn);
      console.log("EMAIL: "+em);
      console.log("PHOTOURL: "+pURL);

      displayName = dpn;
      photoURL = pURL;

    }, function(error)
    {
      // The callback failed.
      console.error(error);
    });
  }

}

In my console I see that the UID is getting loaded, the correct data is getting fetched,
but I cannot seem to get the result on my view? It just stays empty.

Can somebody explain what I’m missing or what I’m supposed to do?

Thanks in advance!


#2

First, you need to declare displayName and photoUrl in your class. Then change references to both to this.displayName and this.photoUrl, respectively.

Second, you need to utilize the fat arrow functions (i.e. =>) rather than JS style function. So change, function(snapshot) to snapshot =>, and function(error) to error =>.

The former change makes the variables available to the view, the latter makes sure that the context of this is the expected one. (As in JavaScript the context is weird and ever changing)

(Apologies for any typos, as I typed this on my phone)


#3

You are my personal hero of the day!
So if I’m correct:
the this.variable makes it so that the view goes looking for this value &
the snapshot => makes it so that the context can be changed once found ?


#4

Alright, I’m at my PC now so I can go a bit more in-depth.

So the class that is defined for each page is a controller, while the HTML is the view. So the controller is in charge of various things as you’ve seen, like loading data, handling events, and also (and most importantly in this case) exposing things (i.e. variables) to the view. So in your original code, you were defining variables outside of the class, which means that the view wasn’t able to access them (as the view can only access things exposed by the controller).

So, Fat Arrows. In traditional JS, this is an ever changing variable depending on the calling context. This isn’t really a big deal in traditional JS (usually, anyway) as there’s not really a concept of classes or this.

To expand on this a little more, in your original code you had
function(snapshot) { ... }

The problem with this (in TS/Ionic) is that when you would go to access this, it wouldn’t be the instance of your class! (Which you need to be, as this is where you expose the variables to the view!)

So what fat arrows do is retain the reference to the instance of your class, i.e. make sure that this is actually “this”.

I hope that explains it a little more.