简体   繁体   中英

Accessing items pushed into array

Within my firebase data I have a games object, and a players object. Nested within the players object are unique keys that match the games unique keys, these are the games that include players. Then nested within the game unique keys (inside the players object) are the keys of the actual players who entered that particular game. what I'm trying to accomplish is an ng-repeat of only the games that the current user (player.uid) has joined. So in the code below I'm checking if the players id (inside the players object) matches their firebase UID, and if it does I'm pushing that into empty array, then the loop should iterate over that array and if the keys in the array match the keys in the games object...it returns true; switching the class from 'hideGames', which has a display of none, to 'show games' which has a display of block. This works well if I add the keys to the commented out gamesToShow array, but not in the actual gamesToShow array that should be populated from the loop. What am I doing wrong here? I have tried moving the gamesToshow array but it still logs empty. What do I need to do in order for it to be usable in the for loop? Thanks in advance, I posted relevant code, if any thing else is needed let me know. Thanks everyone.

"games":{  
      "-JwYx6ckhITt2GWOmzLy":{  
         "date":"8/27/2015",
         "host":"Anthony DeVenuto",
         "hostEmail":"anthonydevenuto@gmail.com",
         "location":{  
            "address":"1234 Crooked Rd, Chicago Illl",
            "course":"Crooked Stick"
         },
         "name":"Crooked Stick Run",
         "rules":{  
            "amount":"21",
            "format":"Match Play",
            "holes":"9",
            "perBirdie":"DOES NOT APPLY",
            "perSkin":"DOES NOT APPLY",
            "time":"12:00pm"
         }
      },
      "-Jwi64w0weox4vxIbz8J":{  
         "date":"8/23/2015",
         "host":"Anthony DeVenuto",
         "hostEmail":"anthonydevenuto@gmail.com",
         "location":{  
            "address":"1234 fdsadgad",
            "course":"West Hills Gathering"
         },
         "name":"West Side Shuffle",
         "rules":{  
            "amount":"21",
            "format":"Match Play",
            "holes":"18",
            "perBirdie":"DOES NOT APPLY",
            "perSkin":"DOES NOT APPLY",
            "time":"1:00pm"
         }
      },
      "-Jwx-f7HnjIKdkMnM16D":{  
         "date":"8/23/2015",
         "host":"Andy",
         "hostEmail":"andy@andy.com",
         "location":{  
            "address":"1234 First Ave",
            "course":"WestCode Hills"
         },
         "name":"WestCode Hustle",
         "rules":{  
            "amount":"12",
            "format":"Match Play",
            "holes":"18",
            "perBirdie":"DOES NOT APPLY",
            "perSkin":"DOES NOT APPLY",
            "time":"1:00pm"
         }
      }
   },
   "players":{  
      "-JwYx6ckhITt2GWOmzLy":{  
         "-Jx1uw6iY87HoNJfAngF":{  
            "email":"andy@andy.com",
            "id":"simplelogin:19",
            "name":"Andy"
         }
      },
      "-Jwi64w0weox4vxIbz8J":{  
         "-Jx1uxoJ0H8Pycp7V12s":{  
            "email":"andy@andy.com",
            "id":"simplelogin:19",
            "name":"Andy"
         }
      },
      "-Jwx-f7HnjIKdkMnM16D":{  
         "-Jx1nbKxyLcbwFFIGjh4":{  
            "email":"anthonydevenuto@gmail.com",
            "id":"simplelogin:22",
            "name":"Anthony DeVenuto"
         }
      }
   },
   "users":{  }
}

JS

var player = auth.$getAuth();

  $scope.displayGames = function(game){
  var gamesToShow = [];
  // var gamesToShow = ['-JwYx6ckhITt2GWOmzLy', '-Jwi64w0weox4vxIbz8J'];

  var playersRef = fire.child('players');
  playersRef.on('value', function(snapshot){
    var gamesObjects = snapshot;
    gamesObjects.forEach(function(snapshot){
      var gameKeys = snapshot.key()
      var playerKeys = snapshot;
      playerKeys.forEach(function(snapshot){
        if (snapshot.val().id == player.uid) {
          gamesToShow.push(gameKeys);
          console.log(gameKeys)
        }
      });
    });
  });
    for (var i=0;i<gamesToShow.length;i++) {
      var uniqueKeys = gamesToShow[i];
      if (game.$id == uniqueKeys) {
        return true;
      }
    };
  }

HTML template:

<h1>Dashboard</h1>
  <ul>
    <li class="hideGames" ng-repeat="game in games" ng-class="{showGames:displayGames(game)}">
      <a href="#" ng-click="gameDetails(game)">Course: {{ game.name }} <br> Date:{{ game.date }}<br></a>
      <a href="#" ng-click="removeDashboardGame(game)">Remove</a>
    </li>
  </ul>

If I parse correctly, you are trying to get a list of the games that the current user is playing in. If so, this code will do the trick:

var uid = 'simplelogin:19';
var gamesToShow = [];
ref.child('players').on('value', function(gamesSnapshot) {
  gamesSnapshot.forEach(function(gameSnapshot) {
    var playerKeys = Object.keys(gameSnapshot.val());
    playerKeys.forEach(function(playerKey) {
      var player = gameSnapshot.val()[playerKey];
      if (player.id === uid) {
        console.log(gameSnapshot.key());
        gamesToShow.push(gameSnapshot.val());
      }
    });
  });
  console.log(gamesToShow);
});

A JSBin that shows this code working: http://jsbin.com/selisa/edit?js,console

But not that your data structure is pretty bad for the goal you're trying to accomplish. You're looping through the players to match them by their key and that makes things complex. Since players have an existing natural key (their uid) and each player can probably join each game only once, you're better off storing the players in a game under their uid:

{
  "-JwYx6ckhITt2GWOmzLy": {
      "simplelogin:19": true
  },
  "-Jwi64w0weox4vxIbz8J": {
      "simplelogin:19": true
  },
  "-Jwx-f7HnjIKdkMnM16D": {
      "simplelogin:22": true
  }
}

With this data structure, you can simply get the list of games with a Firebase query:

ref.child('players')
   .orderByChild('simplelogin:19')
   .equalTo(true)
   .once('value', function(snapshot) { 
       console.log(snapshot.val()); 
   });

As is quite often the case, you can prevent many headaches by optimizing your data structure for how you intend to use it.

Yet another alternative you may want to consider is to store the games for each player/user under their /users node. That way you wouldn't even need a query, but you could directly access the games with:

ref.child('users').child('simplelogin:19').child('games').once('value', ...

That's going to be the best-performing solution, since it doesn't even require a query to access the games.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM