0

I am trying to iterate over an array and add some HTML tags. I have tried .map, but since it returns another array I can see the commas in the HTML. I tried .forEach and it works when I log it to the console, but I get undefined in the HTML. I searched for an answer to this and found a couple answers pointing to no return to the calling function. Some had a callback and were returning from the call back but not to the calling function. I can't find where I'm not returning.

I know wrapTag is returning since I can log it to the console, but it doesn't seem to be passed to wrappedItems.

Is there a return I'm missing or is it something with .forEach that I'm not implementing correctly?

$(document).ready(function(){ let objR = { key1:"5", key2:"8", key3:"6", key4:"9", key5: {subKey1:"1",subKey2:"2",subKey3:"3",subKey4:"4"} } let arr = []; let html = ''; const s = x => document.getElementById(x); const isObject = val => (typeof val === "object") ? true : false; const keyValueToArray = (obj) => { for(let key in obj) { let value = obj[key], n = []; if(!isObject(value)){ n.push(key, value); arr.push(n); } else{ arr.push(key); keyValueToArray(value); } } return arr; } const typeCheck = (x) => { console.log(typeof x); return x; } const wrapTag = (item, tag, i) => isObject(item) ? '<' + tag + '>' + item[0] + ' : ' + item[1] + '</' + tag +'>' :'<' + tag +'>' + item + ':</' + tag +'>'; //const wrappedItems = keyValueToArray(objR).map(x => wrapTag(x, 'li')) const wrappedItems = keyValueToArray(objR).forEach(function(x, i, z){ var res = wrapTag(x, 'li'); console.log(res); return res; }) html = '<ul>'; html += wrappedItems; html += '</ul>'; console.log(`html = ${html}`); s('cards').innerHTML = html; 

});

I made forEach work by wrapping it in an anonymous function and using let to declare res. I had to pass in obj to the wrappedItems function, but that's not far from what I was trying to achieve. Here's the revised function.

 const wrappedItems = (obj) => { let res = ''; keyValueToArray(objR).forEach(function(x, i, z){ res += wrapTag(x, 'li'); console.log(res); }); return res; } html = '<ul>'; html += wrappedItems(objR); html += '</ul>'; 

1 Answer 1

1

forEach() doesn't return anything so wrappedItems is undefined. (docs). You might try map() instead:

keyValueToArray(objR).map(function(x, i, z){} 

Or push to a new array inside forEach()

EDIT:

Once you've mapped the values you can make them into one string without commas using join() like this:

html += wrappedItems.join(" "); // or whatever you want to join with (maybe "\n") 

This should give you:

<ul><li>key1 : 5</li> <li>key2 : 8</li> ... 
Sign up to request clarification or add additional context in comments.

4 Comments

I tried .map, as you can see in my code it's commented out, I get commas in my HTML since it returns an array. I was trying to do this without using a for - in loop.
@jwolf Oh yeah, I skipped the comment -- sorry about that. See edit.
I'll try that, since it's cleaner than my solution above.
The .join(' ') is what I was missing. I did it a little different so I make the code more generic. const wrappedItems = (obj) => keyValueToArray(obj).map(x => wrapTag(x, 'li')).join('');

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.