0

merry christmas/happy holidays! I am trying to get a variable from a function using js/firebase and use said variable in another function. Issue is that b/c firebase is async, the variable is loaded after the function which needs it runs. My code below.

My Question: How do I get convoId to populate from initChatroom() before loadMessages() is executed?

// Global Variable
var convoId = '';

// Triggers when the auth state change for instance when the user signs-in or signs-out.
MyApp.prototype.onAuthStateChanged = function(user) {
  if (user) { // User is signed in!

    // We load currently existing chat messages.
    this.initChatRoom();
    this.loadMessages();
   }
};

//Get chatroom name
MyApp.prototype.initChatRoom = function(){

  var userId = this.auth.currentUser.uid;
  return this.database.ref('/user_profiles/' + userId).once('value').then(function(snapshot) {
    var agentAssigned = snapshot.val().agent_assigned;

    //Gets Chatroom details
    if (snapshot.hasChild("agent_assigned")){

        userNameExtract = snapshot.val().nickname;

    //First five user & first five counterparty
        var receieverID = agentAssigned;
        var senderId = userId;
        var receiverIDFive = receieverID.substring(0,5);
        var senderIdFive = senderId.substring(0,5);

        if (senderIdFive > receiverIDFive){

            convoId = senderIdFive + receiverIDFive;
        }
        else{
            convoId = receiverIDFive + senderIdFive;
        }

        console.log("chatroom name", convoId);
    }
    else{ }
  });

}

// Loads chat messages history and listens for upcoming ones.
MyApp.prototype.loadMessages = function() {

  console.log("loadMessage", convoId); //CONVO ID is not loaded yet :(

  this.messagesRef = this.database.ref('messages/' + convoId + '/');

  // Make sure we remove all previous listeners.
  this.messagesRef.off();

  // Loads the last 12 messages and listen for new ones.
  var self = this;
  // Loads the last 12 messages and listen for new ones.
  var setMessage = function(data) {

    var dataVar = data.val();

    self.displayMessage(data.key, dataVar.userName, dataVar.text, dataVar.type, dataVar.senderId);
  };

  this.messagesRef.limitToLast(12).on('child_added', setMessage);
  this.messagesRef.limitToLast(12).on('child_changed', setMessage);
};
4
  • If the second function relies on the execution of the first, then why don't you just call it in there (e.g.: in the callback functor of the database query)? Commented Dec 25, 2016 at 19:11
  • I had tried this but i keep getting "Uncaught (in promise) TypeError: Cannot read property 'loadMessages' of undefined" Commented Dec 25, 2016 at 19:18
  • In that case you are probably missing a .bind(this) after the closing brace (so function(snapshot) { //code }.bind(this) should work). Or you should be using ES6 fat arrow functions to have this done automatically Commented Dec 25, 2016 at 19:23
  • boom! that was it, thank you very much. if you add it as an answer i can upvote/mark as answered. Commented Dec 25, 2016 at 19:43

1 Answer 1

1

So as per the comments:

As the function loadMessages is dependent on the results of the function initChatRoom it should be called from there, within the callback functor to the database call (which returns the required data). However this functor needs to be bound to the correct context, so it has to be defined as:

this.database.ref('/user_profiles/' + userId).once('value').then(function(snapshot) {
  // operations on data
  this.loadMessages()
}.bind(this)

Alternatively, using ES6 "fat arrow" syntax it could be written as:

this.database.ref('/user_profiles/' + userId).once('value').then((snapshot) => {
  // operations on data
  this.loadMessages()
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.