Steve Medley Steve Medley - 5 months ago 24
Javascript Question

forEach versus for in

I have several things I am trying to replace with forEach (as is a requirement for a class I'm taking) however not one of them works:

My original For in code (This works correctly and displays the content):

for (var i in education.schools) {
$('#education').append(HTMLschoolStart);

var formattedName = HTMLschoolName.replace('%data%', education.schools[i].name).replace('#', education.schools[i].url);
var formattedLocation = HTMLschoolLocation.replace('%data%', education.schools[i].location);
var formattedDegree = HTMLschoolDegree.replace('%data%', education.schools[i].degree);
var formattedMajors = HTMLschoolMajor.replace('%data%', education.schools[i].majors);
var formattedDates = HTMLschoolDates.replace('%data%', education.schools[i].dates);
var formattedNameDegree = formattedName + formattedDegree;


$('.education-entry:last').append(formattedNameDegree);
$('.education-entry:last').append(formattedDates);
$('.education-entry:last').append(formattedLocation);
$('.education-entry:last').append(formattedMajors);
}


My forEach variation(Nothing is displayed, all content disappears):

education.schools.forEach(function() {
$('#education').append(HTMLschoolStart);

var formattedName = HTMLschoolName.replace('%data%', education.schools[i].name).replace('#', education.schools[i].url);
var formattedLocation = HTMLschoolLocation.replace('%data%', education.schools[i].location);
var formattedDegree = HTMLschoolDegree.replace('%data%', education.schools[i].degree);
var formattedMajors = HTMLschoolMajor.replace('%data%', education.schools[i].majors);
var formattedDates = HTMLschoolDates.replace('%data%', education.schools[i].dates);
var formattedNameDegree = formattedName + formattedDegree;


$('.education-entry:last').append(formattedNameDegree);
$('.education-entry:last').append(formattedDates);
$('.education-entry:last').append(formattedLocation);
$('.education-entry:last').append(formattedMajors);
})


The second one is an if statement that I am supposed to replace part of with a forEach.

The if statement works fine like this only problem is it is only good for exactly 7 items, if I were to add anymore to the array I would have to also update this:

if (bio.skills.length > 0) {
$('#header').append(HTMLskillsStart);

var formattedSkill = HTMLskills.replace('%data%', bio.skills[0]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[1]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[2]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[3]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[4]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[5]);
$('#skills').append(formattedSkill);
var formattedSkill = HTMLskills.replace('%data%', bio.skills[6]);
$('#skills').append(formattedSkill);
}


The forEach loop code(Instead of displaying each item in the array it displays ALL items in the array seven times, basically it does seem to iterate through it the correct number of times but outputs all 7 items to each iteration):

if (bio.skills.length > 0) {
$('#header').append(HTMLskillsStart);

bio.skills.forEach(function(){
var formattedSkill = HTMLskills.replace('%data%', bio.skills);
$('#skills').append(formattedSkill);
})
}

Answer

Try declaring the index in the forEach callback function:

education.schools.forEach(function(val, i) {
    $('#education').append(HTMLschoolStart);

    var formattedName = HTMLschoolName.replace('%data%', education.schools[i].name).replace('#', education.schools[i].url);
    var formattedLocation = HTMLschoolLocation.replace('%data%', education.schools[i].location);
    var formattedDegree = HTMLschoolDegree.replace('%data%', education.schools[i].degree);
    var formattedMajors = HTMLschoolMajor.replace('%data%', education.schools[i].majors);
    var formattedDates = HTMLschoolDates.replace('%data%', education.schools[i].dates);
    var formattedNameDegree = formattedName + formattedDegree;


    $('.education-entry:last').append(formattedNameDegree);
    $('.education-entry:last').append(formattedDates);
    $('.education-entry:last').append(formattedLocation);
    $('.education-entry:last').append(formattedMajors);
});

Per Mozilla:

callback is invoked with three arguments:

  • the element value

  • the element index

  • the array being traversed

EDIT:

As Andreas mentions in the comments, if the forEach is running off of the education.schools array, then you can use the first parameter(val) in the callback instead of education.schools[i] to get the current item.