2

I'm using AngularJS in a Firebase app and I have a function where I do some inner join to get some data. More details here. After getting the response from the firebase api I create an object and push it into an array (a scope variable). I see in the debug that the data has been retrieved and that the $scope variable is filled correctly. The problem is that it is not showing in the ng-repeat.

My function:

$scope.getMessagesByRegion = function(regionId){

    console.log('Function start');
    var rootRef = firebase.database().ref();
    var regionMessagesRef = rootRef.child("region_messages/"+ regionId);
    $scope.messages_by_region = []; // Here I reset the scope variable

    regionMessagesRef.on('child_added', function(rmSnap) {

        var messageRef = rootRef.child("messages/"+rmSnap.key);
        messageRef.once('value').then(function(msgSnap){

            var msg = {
                key : msgSnap.key,
                name : msgSnap.val().name,
                type : $scope.getTypeName(msgSnap.val().type),
                show_only_once : rmSnap.val().show_only_once,
                pre_requisite_message : rmSnap.val().pre_requisite_message
            }
            console.log(msg); // here I see the object in the console. it is OK
            $scope.messages_by_region.push(msg); // pushing the item
            console.log('----------------');
            console.log($scope.messages_by_region);
        })

    });
}

My HTML:

            <table class="table">
                <thead>
                <tr>
                    <th>Message name</th>
                    <th>Type</th>
                    <th>Show only once</th>
                    <th>Pre requisite</th>
                </tr>
                </thead>
                <tbody>
                <tr ng-repeat="msg in messages_by_region">
                    <td ng-bind="msg.name"></td>
                    <td ng-bind="msg.type"></td>
                    <td ng-bind="msg.show_only_once"></td>
                    <td ng-bind="msg.pre_requisite_message"></td>
                </tr>
                </tbody>
            </table>

This is what I see in the console:

enter image description here

The problem is that even having an object in the array it is not shown in the view. It is like there was an empty array set to the $scope.messages_by_region variable

I'm having a hard time figuring out what I'm doing wrong. Can you see what's wrong with my function?

Thanks for any help.

2
  • Try adding the console.log($scope.messages_by_region); to a test function and make a ng-click call this function and see what happens. Also do you see any error in the console? Commented Dec 12, 2016 at 17:49
  • did you try without ng-bind directive? <td>{{msg.name}}</td> Commented Dec 12, 2016 at 17:49

3 Answers 3

2

try,

$scope.$apply(function(){
 $scope.messages_by_region.push(msg);
});

or,

$scope.messages_by_region.push(msg);
$scope.$apply();
Sign up to request clarification or add additional context in comments.

2 Comments

Worked! Thanks! Apply receiving a function so it checks only for the value affected inside that function?
you calling a non angular function messageRef.once therefore you have to tell the angular that some $scope variable changed .
1

Since you're using async functions (Cosuming of firebase API) you should tell angular to refresh the HTML;

Use

$scope.$diggest()

More information you can find on https://www.sitepoint.com/understanding-angulars-apply-digest/

1 Comment

Thanks! I had to use $scope.$apply()
1

As you are performing Async calls you need to tell angular to refresh the changes in the value with $apply call you can do it with:

$scope.getMessagesByRegion = function(regionId) {

  console.log('Function start');
  var rootRef = firebase.database().ref();
  var regionMessagesRef = rootRef.child("region_messages/" + regionId);
  $scope.messages_by_region = []; // Here I reset the scope variable

  regionMessagesRef.on('child_added', function(rmSnap) {

    var messageRef = rootRef.child("messages/" + rmSnap.key);
    messageRef.once('value').then(function(msgSnap) {
        var msg = {
          key: msgSnap.key,
          name: msgSnap.val().name,
          type: $scope.getTypeName(msgSnap.val().type),
          show_only_once: rmSnap.val().show_only_once,
          pre_requisite_message: rmSnap.val().pre_requisite_message
        }

      $scope.$apply(function() {
        console.log(msg); // here I see the object in the console. it is OK
        $scope.messages_by_region.push(msg); // pushing the item
        console.log('----------------');
        console.log($scope.messages_by_region);
      });
    });
  });
}

For more information on this behavior you can also read article describing the problem here

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.