cassiusclay
cassiusclay

Reputation: 386

Watching Firebase query in angularjs

I'm building an application in Angular with Firebase and one aspect of it is one-to-one chat. I'm querying Firebase to see if a chat room exists already between the user currently accessing the application and the user they are attempting to chat with. If it exists, I am trying to apply that room to the scope as the selected room. I'm using "Messages" service to run the query.

this.roomQuery = function(user1ID, user2ID) {
  roomsRef.orderByChild("user1").equalTo(user1ID).on("child_added", function(snapshot) {

    if (snapshot.val().user2 == user2ID) {
      self.selectedRoom = snapshot.key();
      console.log(self.selectedRoom);
    } else {
      self.selectedRoom = null;
    }


  })
}

and in my controller I am using:

$scope.$watch(
    function(){ return Messages.selectedRoom },

    function(newValue, oldValue) {
      $scope.selectedRoom = newValue;
    }
    )

This $scope.$watch method has worked for me with everything else and it seems to sometimes work in this case. The console log always prints out the correct value for Messages.selectedRoom, but the $scope.selectedRoom sometimes does not update. Any idea what is happening here? I'm very confused. If it's logging to the console properly, shouldn't it be updated in the scope?

Upvotes: 2

Views: 388

Answers (2)

cassiusclay
cassiusclay

Reputation: 386

David got me to the solution I needed. For anyone with a similar issue, here is how I implemented it:

this.roomQuery = function(user1, user2) {
  var query = roomsRef.orderByChild("user1").equalTo(user1ID)

  return $firebaseArray(query).$loaded();
}

I used $firebaseArray instead of Object and in my controller:

$scope.getRoom = function() {
    Messages.roomQuery($scope.user1.id, $scope.user2.$id).then(function(data)
    {
      $scope.data = data;
      for(var i=0, len = data.length; i < len; i++){
        if (data[i].user2 == $scope.user2.$id) {
          $scope.selectedRoom = data[i].$id;
        }
      }
    }
    )
  }

Apologies for the variable names being a little confusing. I altered them for the sake of this post.

Upvotes: 0

David East
David East

Reputation: 32604

Angular's $digest is unaware of when a your Firebase query completes. You might find it easier to use AngularFire in this case.

this.roomQuery = function(user1ID, user2ID) {
  var query = roomsRef.orderByChild("user1").equalTo(user1ID);
  return $firebaseObject(query).$loaded();
};

this.roomQuery("1", "2")
  .then(function(data) {
    // do your check here
  });

The $firebaseObject() takes in a ref or a query and knows when to call digest on your behalf.

You might want to check out using resolve in the router to inject the roomQuery into the router, since it returns a promise with .$loaded().

Upvotes: 1

Related Questions