0

I have this firebase data:

{
    "userData": {
        "user01": {
          "name": "User One"
          "provider": "provider0001"
        },
        "user02": {
          "name": "User Two"
          "provider": "provider0001"
        },
        "user03": {
          "name": "User Three"
          "provider": "provider0002"
        }
    },
    "provider": {
        "provider0001": {
          "users": {
            "user01": true,
            "user02": true
          }
        },
        "provider0002": {
          "users": {
            "user03": true
          }
        }
    }
}

controller

vm.provider = $firebaseObject(ref.child('provider').child('provider0001'));

simple html

<ul>
    <li ng-repeat="user in $ctrl.provider.users">
        {{user}}
    </li>
</ul>

Why I cannot list {{user}} as object? The above will display list of true's, but how can I access the user object it self?

vidriduch
  • 4,753
  • 8
  • 41
  • 63
  • you have make json object array then you can use ng-repeat and display records. – Jayant Patil Mar 14 '17 at 12:17
  • You'll need to do a client-side to get the data for each user. See http://stackoverflow.com/questions/30299972/joining-data-between-paths-based-on-id-using-angularfire. This is not as slow as you may fear. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 – Frank van Puffelen Mar 14 '17 at 14:39

2 Answers2

3

You need to map the keys (your userId's) in the users-object, to the values in your userData-object. You can get the keys in an ng-repeat-directive like this:

ng-repeat="(key, value) in $ctrl.provider.users"

Then in your controller you need to add the userData object to your controller scope:

vm.userData = $firebaseObject(ref.child('userdata'));

So you can implement your ng-repeat like this:

<ul>
    <li ng-repeat="(key, value) in $ctrl.provider.users" 
        ng-init="user = $ctrl.userData[key]">
        {{user}}
    </li>
</ul>

With that said, you probably ought to do this mapping when you retrieve the data in the controller initially. Something like this:

function loadData(){
    var providerUsers = $firebaseObject(ref.child('provider').child('provider0001').child('users'));
    var userData = $firebaseObject(ref.child('userData'));
    vm.users = [];

    angular.forEach(providerUsers, function(value, key) {
        vm.users.push(userData[key]);
    });
}

Then you can just iterate using ng-repeat over this new vm.users-array.


Update

Here's a solution where you only retrieve the actual mapped users. It makes a query for each user, since I couldn't find a decent way to join two collections by key using just a single Firebase query.

function loadData(){
    var userRef = ref.child('provider').child('provider0001').child('users');
    var userDataRef = ref.child('userData');
    vm.users = [];

    userRef.once('value', function(snapshot){
        snapshot.forEach(function(userId){
            userDataRef.child(userId.key()).once("value", function(user){
                $scope.$apply(function () {
                    vm.users.push(user.val());
                });
            });
        })
    });
}

My familiarity with Firebase is very limited so there might be better solutions out there

Nikolaj Dam Larsen
  • 5,455
  • 4
  • 32
  • 45
  • but what id userdata has 1000+ records, is really necessary to load all that data? – vidriduch Mar 14 '17 at 12:32
  • It shouldn't be, but you need to use firebase to do the mapping/filtering then. I'll try to cook up an example. – Nikolaj Dam Larsen Mar 14 '17 at 12:39
  • @vidriduch I've updated my answer with a solution that doesn't load all the `userData` at once. Instead it loads each user's data separately. Whether this is more performant, I cannot say, but Firebase should be using pipelining, so all queries would be performed in parallel. – Nikolaj Dam Larsen Mar 14 '17 at 17:24
1
<ul>
  <li ng-repeat="(key,user) in $ctrl.provider.users">
   {{key}}:{{user}}
  </li>

key will give the key of the user and user will give value

Ankit Kumar Gupta
  • 1,256
  • 1
  • 10
  • 23