0

I am very new to Javascript and trying to print out a selected teams NFL schedule. I have created and populated a drop down menu with all the teams. I want the user to be able to select their team and see their schedule. I am able to return the whole list (every game), but I cannot figure out how to only return the games of the selected team. Here is what the data looks like that I am using.

"Schedule": [
 {
 "gameId": "1",
 "gameWeek": "1",
 "gameDate": "2018-09-06",
 "awayTeam": "ATL",
 "homeTeam": "PHI",
 "gameTimeET": "8:20 PM",
 "tvStation": "NBC",
 "winner": "PHI"
 },
 {
 "gameId": "2",
 "gameWeek": "1",
 "gameDate": "2018-09-09",
 "awayTeam": "BUF",
 "homeTeam": "BAL",
 "gameTimeET": "1:00 PM",
 "tvStation": "CBS",
 "winner": "BAL"

Here is the code that returned my all the games.

function processData(data){
 schedule = data["Schedule"];
 for(eachGame in schedule){
 var game = schedule[eachGame];
 var week = game["gameWeek"];
 var homeTeam = game["homeTeam"];
 var awayTeam = game["awayTeam"];
 var winner = game["winner"];
 var tableRow = "<tr><td>" + week + "</td><td>" + homeTeam + "</td><td>" + awayTeam + "</td><td>" + winner + "</td></tr>";
 $("#output").append(tableRow);
 }
}

I need to return when the awayTeam or homeTeam are the team that the user selected.

Thanks!

asked Nov 15, 2018 at 20:56
4
  • How do you get which team the user selected? Commented Nov 15, 2018 at 21:00
  • let team = $('#teamSelect').val(); Commented Nov 15, 2018 at 21:02
  • You could use filter() to do that. let teamSchedule = schedule.filter(g => g.homeTeam === team || g.awayTeam === team); I'm not submitting this as an answer because I feel that this question is likely a duplicate. Commented Nov 15, 2018 at 21:13
  • Possible duplicate of Javascript: How to filter object array based on attributes? Commented Nov 15, 2018 at 21:15

3 Answers 3

1

To reduce an array down to only a handful of its items, I'd almost always suggest using Array.filter(), however I'm actually going to present an alternative solution first in your case.

If you were to use filter to loop through the items and find the ones you want, and then use a for loop to append them to the table, you'd be looping through some of the same elements twice.

Instead, we can apply our logic to skip the games we don't want inside the same loop, by doing something like this:

//If "team" is neither the away team, nor the home team, skip this game
if (![game.awayTeam, game.homeTeam].includes(team)) return; 

Example 1: (Comments added)

var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };
function setScheduleByTeam(team) {
 let schedule = data["Schedule"]; //Get the schedule
 var $outputTable = $("#output"); //Store the table as a variable
 $outputTable.find("tbody").empty(); //Empty out the current records
 schedule.forEach(function(game) { //For each game in the schedule
 if (![game.awayTeam, game.homeTeam].includes(team)) return; //Skip the record if our team isn't in it
 //Create + Append table row
 var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
 $outputTable.append(tableRow);
 });
}
//On button click
$("body").on("click", "button", function() {
 let team = $('#teamSelect').val(); //Get selected team
 setScheduleByTeam(team); //Update the table to that team's schedule
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
 <option>Select Team</option>
 <option value="Bengals">Bengals</option>
 <option value="Bills">Bills</option>
 <option value="Jets">Jets</option>
</select>
<button>Go!</button>
<table id="output">
 <thead>
 <tr>
 <th>Week</th>
 <th>Home</th>
 <th>Away</th>
 <th>Winner</th>
 </tr>
 </thead>
</table>

However, some might argue for cleanliness, in which case I'd suggest going with the filter method I mentioned earlier:

Example 2 (Comments added)

var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };
//Filter out schedule to only games where awayTeam == team OR homeTeam == team.
//Returns the filtered team's schedule
const getGamesByTeam = (team) => data.Schedule.filter(g => g.awayTeam == team || g.homeTeam == team);
function updateScheduleTable(games) { 
 var $outputTable = $("#output"); //Store table as variable
 $outputTable.find("tbody").empty(); //Remove existing rows
 
 games.forEach(function(game) { //For each game, append to table
 var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
 $outputTable.append(tableRow);
 });
 
}
$("body").on("click", "button", function() {
 let team = $('#teamSelect').val(); //Get the selected team
 let games = getGamesByTeam(team); //Get a filtered array of one team's schedule
 updateScheduleTable(games); //Update the table based on that set of games
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
 <option>Select Team</option>
 <option value="Bengals">Bengals</option>
 <option value="Bills">Bills</option>
 <option value="Jets">Jets</option>
</select>
<button>Go!</button>
<table id="output">
 <thead>
 <tr>
 <th>Week</th>
 <th>Home</th>
 <th>Away</th>
 <th>Winner</th>
 </tr>
 </thead>
</table>

answered Nov 15, 2018 at 21:50
Sign up to request clarification or add additional context in comments.

Comments

0

You need to sort your array of data based on the user's selected team. To do that, you need to use an array method to loop over the array and return values based on logic you put in the loop. To do this, I used the reduce method (IMO the most useful array method).

function filterForSelectedTeam(data) {
 const accumulator = [];
 const team = $('#teamSelect').val();
 const schedule = data["Schedule"];
 // if team has a value this reduce method will return a sorted array
 // based on the logic in the loop.
 return team && schedule.reduce((acc, game) => {
 if (game["homeTeam"] === team || game['awayTeam'] === team) {
 acc.push(game);
 };
 return acc;
 }, accumulator);
}
const data = [] // your data here;
const gamesBySelectedTeam = filterForSelectedTeam(data)
gamesBySelectedTeam.forEach(game => {
 const tableRow = "<tr><td>" + game['gameWeek'] + "</td><td>" + game['homeTeam'] + "</td><td>" + game['awayTeam'] + "</td><td>" + game['winner'] + "</td></tr>";
 $("#output").append(tableRow);
});
answered Nov 15, 2018 at 21:17

6 Comments

While reduce is great if you're trying to go from many-to-one, if you're just looking to filter an array, it's much easier and cleaner to use .filter(). That said, the optimal solution would probably just be to include the "Should I display this game?" logic inside the forEach, that way you can use one loop instead of two :)
@TylerRoper, you should provide your own solution with the filter method to show how much "cleaner and easier" it is. Also, I wouldn't just shove all the logic into a forEach loop. I wanna show the reduction so it is easier to read for other developers. If anything I should chain the two loops.
It was merely a piece of advice. It seems you've chosen to take it as an attack instead. Not to mention, I wrote a one-line filter method in the comments above a few minutes before you submitted your answer.
@TylerRoper didn't take it as an attack. I'm just pointing out that if you have a better solution, you should provide it. That's kinda the whole point of SO.
@TylerRoper, it's just a different way of thinking that is all. I usually use reduce instead of map or filter because it accomplishes the same goals and you can also return different types. I appreciate your help man.
|
0

Here is a way to do this with just a few method calls:

function processData({ Schedule: s }, team) {
 // s is now the equivolent of data['Schedule']
 // Filter the data to get all games where either
 // the away of home team is the team sent in
 // Empty the table so it includes only those games appended below
 // Append the array of games as html elements
 $("#output")empty().append(
 s.filter(g => g.awayTeam === team || g.homeTeam === team)
 .map(g => {
 `<tr>
 <td>${game.gameWeek}</td>
 <td>${game.homeTeam}</td>
 <td>${game.awayTeam}</td>
 <td>${game.winner}</td>
 </tr>`
 })
 );
}

You can append an array of html strings to the DOM and they get handled properly.

answered Nov 15, 2018 at 22:06

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.