0

I'm new in Angular - Firebase development, and I am having problems to understand how to retrieve data nested in two collections. I have a collection named "Orders", which includes a field call "auth", which is the user ID, and I have another collection that is the "User Profile", where its $id is the value of "auth". Inside the User Profile I have a field named roomNumber, and it's content I that I want to retrieve every time I read, in ng-repeat of the Orders.

In my view I was trying to do something like this:

<tr ng-repeat="item in items | filter: searchKeyword ">
  <td align="left">{{item.$id}} -  {{roomNumber(item.$id)}}</td></tr>

roomNumber is a function in my controller

$scope.roomNumber = function(id) {
 var rootRef = new Firebase("https://xxxx-fire-yyyy.firebaseio.com/userProfile"+ '/' + id);
  $scope.userdet = $firebaseArray(rootRef);
  rootRef.on("value", function(rootSnapshot) {
        var key = rootSnapshot.key();
        var childKey = rootSnapshot.child("room").val();
        console.log("room ", childKey)
    });
 return childKey
  }

When I run this code and see results in my js console, strange things happened:

  1. It repeat a lot of times
  2. I can never get the childKey value

I have been reading Firebase documentation, but really I do not understand how to do this "silly" thing, does anybody give me a tip of how to do it?

enter image description here

1
  • Its another firebase data collection Commented Jul 22, 2016 at 1:18

2 Answers 2

1

When you bind a function to the $scope and call it within the html it expects to get an answer back right away when called. So when you query firebase and it takes its sweet time getting you back an answer, angularjs has already gotten an answer of undefined from the function.

So what is happening is that you are registering a callback when you provide the function to rootRef.on and then right after you register the callback you are returning the value of childKey. Unfortunately, childKey only gets set by the callback function (which firebase hasn't executed yet). Therefore angularjs gets an answer of undefined from your roomNumber function.

In order to make this work, you are going to have to get the room numbers beforehand and then probably add them to each of your items in $scope.items then use

<td align="left">{{item.$id}} -  {{item.room}}</td></tr>

instead of

<td align="left">{{item.$id}} -  {{roomNumber(item.$id)}}</td></tr>

To load all the room numbers you could call some function like this one after $scope.items has loaded

for (var i = 0; i < $scope.items.length; i++) {
    var rootRef = new Firebase("https://xxxx-fire-yyyy.firebaseio.com/userProfile"+ '/' + $scope.items[i].$id);
    $scope.userdet = $firebaseArray(rootRef);
    rootRef.on("value", function(rootSnapshot) {
        var key = rootSnapshot.key();
        var childKey = rootSnapshot.val().room;
        $scope.items[i].room = childKey;
    });
}

It would change each of the items to have a reference to the room. Unfortunately, that list wouldn't update as the data updates, so the better solution would be to do that same query in whatever function was getting your items from the server and add the room to each item as it was being added to the items list.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Davis, your comments makes me think different and first I notice one error, I was declaring chilKey as global variable inside the reference, so I declear it before the firebase reference and it works. Also I did a change on my app, I save the room field in the "Orders" collection and this way is easy to get when I browse the data.
I am glad it's working. I am sorry that I didn't provide a full answer, but I was trying to go off of what code you provided.
0

To fix the issue with childKey not reading you need to use this:

var childKey = rootSnapshot.val().room;

instead of this:

var childKey = rootSnapshot.child("room").val();
console.log("room ", childKey)

Reference: https://www.firebase.com/docs/web/guide/retrieving-data.html

2 Comments

Hi Frank, thank you for your quick response, but it still not returning the value of childKey, that is the room. Do you think it's a good practice to use this method : <tr ng-repeat="item in items | filter: searchKeyword "> <td align="left">{{item.$id}} - {{roomNumber(item.$id)}}</td></tr>?, I was reading another article that say this way took a lot of resources of the server, it's that true?
I actually didn't fully figure out what your question was asking when I first posted my answer. I'm going to quickly post a new answer that hopefully clarifies a bit better.

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.