0

for the first iteration of this it works fine, the table is created as intended. However upon the second iteration, the drop down menu is empty. The loops are all working correctly so I'm assuming it has to be something to do with how I am appending the option to select. Appreciate any help.

Javascript

function loadPlayers() { //first ajax call to retrieve players $.ajax({ url: '/players', type: 'GET', contentType: "application/json", success: function(data) { //second ajax call to retrieve presentations $.ajax({ url: '/presentations', type: 'GET', contentType: "application/json", success: function(presentationData) { // loop through each player and append player/presentation to table data.forEach(function(player) { console.log("players") $(".player-table").append( $('<tr>').append( $('<td>').attr('class', 'player-td').append(player.name), $('<td>').attr('class', 'presentation-td').append(player.presentation), $('<td>').attr('class', 'new-presentation-td').append( $('<select>').attr('class', 'new-presentation-dropdown').append( // loop through each presentation in database and add to dropdown presentationData.forEach(function(presentation) { console.log(presentation.name); $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>') }) ) ) ) ) }) } }) } }) } 

HTML

 <table class="player-table"> <tr class="player-name-tr"> <th>Player Name</th> <th>Current Presentation</th> <th>New Presentation</th> </tr> </table> 
4
  • Please look at this link. Your problem is async stackoverflow.com/questions/23283276/… . You should write your second ajax within the .complete() Commented Jul 1, 2016 at 11:07
  • Try to reference the select you create and append the options to the reference. The selector $(".new-presentation-dropdown") has 1 more element for each iteration, might break the thing here. Commented Jul 1, 2016 at 11:14
  • @Memme that was my thinking, but I can't figure out another way to reference the select that works... Commented Jul 1, 2016 at 11:17
  • Anser below exposed exactly what I meant :-) Commented Jul 1, 2016 at 12:54

2 Answers 2

1

You're running the 2nd loop inside the append statement - it means the loop appending the options is run before the <select> is created. Since the select element has not yet been created $(".new-presentation-dropdown") matches nothing in the DOM. Moving the loop appending the options outside of all the .append() statements should fix this issue:

data.forEach(function(player) { console.log("players"); $(".player-table").append( $('<tr>').append( $('<td>').attr('class', 'player-td').append(player.name), $('<td>').attr('class', 'presentation-td').append(player.presentation), $('<td>').attr('class', 'new-presentation-td').append( $('<select>').attr('class', 'new-presentation-dropdown') ) ) ); // loop through each presentation in database and add to dropdown presentationData.forEach(function (presentation) { console.log(presentation.name); $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>') }) }); 

However $(".new-presentation-dropdown") will match every <select> created so that'll give strange results. I'd suggest you assign the $('<select>') to a variable and append the options to the variable, before appending it to the table, like this: (Untested but should work)

data.forEach(function(player) { console.log("players"); var $newPresentationDopdown = $('<select>').attr('class', 'new-presentation-dropdown'); // loop through each presentation in database and add to dropdown presentationData.forEach(function (presentation) { console.log(presentation.name); $newPresentationDopdown.append('<option>' + presentation.name + '</option>') }); $(".player-table").append( $('<tr>').append( $('<td>').attr('class', 'player-td').append(player.name), $('<td>').attr('class', 'presentation-td').append(player.presentation), $('<td>').attr('class', 'new-presentation-td').append($newPresentationDopdown) ) ); }); 
Sign up to request clarification or add additional context in comments.

2 Comments

Ah thank you for the explanation, all makes sense now and is working as intended. Many thanks!
To avoid some overhead you could create the select outside the 1st loop, that way you only iterate it once (since it looks like the presentationData is the same for every player?) and just append it for each player.
0

Based on append method documentation you can pass function by below feature:

A function that returns an HTML string, DOM element(s), text node(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.

Whiles below code is inconsistent by that rule:

$('<select>').attr('class', 'new-presentation-dropdown').append( // loop through each presentation in database and add to dropdown presentationData.forEach(function(presentation) { console.log(presentation.name); $(".new-presentation-dropdown").append('<option>' + presentation.name + '</option>') }) ) 

You don't return any result in your passed function.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.