Max Henchman Max Henchman - 26 days ago 6
Javascript Question

$.each within $.each using JS multi-dimensional obj

I have an object created for some footer content like so:

var $footerObj = {
"one" : {
"title" : "One",
"links" : {
"A" : {
"title" : "One A",
"url" : "#",
"external" : true
},
"B" : {
"title" : "One B",
"url" : "#",
"external" : true
},
"C" : {
"title" : "One C",
"url" : "#",
"external" : false
}
}
},
"two" : {
"title" : "Two",
"links" : {
"A" : {
"title" : "Two A",
"url" : "#",
"external" : false
},
"B" : {
"title" : "Two B",
"url" : "#",
"external" : false
}
}
}
};


I am attempting to use jQuery's $.each to output this into some footer links.

$.each($footerObj, function(key, value) {

$('.footer__links').append('<ul class="footer__list"></ul>');

var $footerList = $('.footer__list');

$.each(value.links, function(subkey, subvalue) {

$footerList.append('<li class="footer__item"><a class="footer__link" href="' + subvalue.url + '">' + subvalue.title + '</a></li>');

});

});


This is what I have but this causes the data in "two" to be outputted twice. I believe it's value.links in the 2nd $.each which is wrong but I've been going mad trying all different variations with no luck - any help would be appreciated!

Thanks

Answer

When you append to a class it will append to every item that has that class, on the second object, there will be two with that calss, on the third there will be three, etc. The solution is to append to the one you created on that loop instead of every element with that class name. Do this in your outer each() loop instead:

var $footerList = $('<ul class="footer__list"></ul>');
$('.footer__links').append($footerList);

So it looks like this:

$.each($footerObj, function(key, value) {

    var $footerList = $('<ul class="footer__list"></ul>');

    $('.footer__links').append($footerList);

    $.each(value.links, function(subkey, subvalue) {

        $footerList.append('<li class="footer__item"><a class="footer__link" href="' + subvalue.url + '">' + subvalue.title + '</a></li>');

    });

});