Unexpected comma using map()
I've an array with a list of elements and I'm trying to append this list to an HTML element using template strings:
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
${description.map(
function(work) {
return `<li>${work}</li>`
}
)}</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
As a result I get an unexpected comma between each list element. (You can see this when you run the code snippet above.)
How can I avoid this?
Solution 1:
Explanation
template literals use the toString()
method which by default joins the returned array by map
with a ,
.
To avoid this "problem" you can use join('')
Code
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
${
description.map(function(work) {
return `<li>${work}</li>`
}).join('')
}
</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Solution 2:
.map()
returns an array. You probably want to return a string containing the array elements concatenated together. You can do that with .join('')
:
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
${description.map(
function(work) {
return `<li>${work}</li>`
}
).join('') /* added .join('') here */}</ul>
</div>
`
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Solution 3:
As others have pointed out (which I'm going to repeat for completeness sake), Array.prototype.map
returns a new array which contains the elements that are altered in the function that is passed to it.
When you concatenate an array to a string (which is what is happening here), it will convert the array to a string as well. And when an array is converted to a string, it is automatically joined using commas.
const arr = ['<a>', '<b>'];
console.log(arr + ""); // <a>,<b>
Besides using .join()
to explicitly pass an empty string as the separator, you can also replace the .map()
with a Array.prototype.reduce
to reduce the array to a single value.
description.reduce((acc, work) => acc + `<li>${work}</li>`, '')
So the complete code would look like this:
var description = [
'HTML & CSS',
'Javascript object-oriented programming',
'Progressive Web apps (PWAs)',
'Website Performance Optimization',
'Webpack and Gulp workflows',
'Fullstack React.js',
'Web Components',
'Responsive web design',
'Sketch design',
'GraphQL and Relay'
]
$('body').append(
`
<div class="description">
<ul>
${
description.reduce((acc, work) => acc + `<li>${work}</li>`, '')
}
</ul>
</div>
`
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Solution 4:
For simple your code, i just use like this:
${description.map((work) => <li>${work}</li>
).join('')}