I just started to use template literals and tagged template literals. But I'm running into a problem when trying to render a template literal because it renders an extra substitution that I can wonder where it comes from.
This is what I have tried:
My data
var data = {
login: "john_12",
name: "John",
bio: "developer",
email: "jdev@mail.com"
}
My tag function
function replaceNullData(strings, ...parts) {
var checkedMarkup = "";
strings.forEach((string, index) => {
if (!parts[index]){
parts[index] = "data no available";
}
checkedMarkup += string + parts[index];
});
return checkedMarkup;
}
My template literal
var summaryMarkup = replaceNullData`
<div>
<p>Username: ${data.login}</p>
</div>
<div>
<p>Name: ${data.name}</p>
</div>
<div>
<p>Bio: ${data.bio}/<p>
</div>
<div>
<p>Email: ${data.email}</p>
</div>
`;
Now, if I do console.log(summaryMarkup);
, I obtain this:
<div>
<p>Username: john_12</p>
</div>
<div>
<p>Name: John</p>
</div>
<div>
<p>Bio: developer/<p>
</div>
<div>
<p>Email: jdev@mail.com</p>
</div>
data no available <------- THIS IS WHAT SHOULDN'T APPEAR
There is an extra "data no available" at the end. It's like the tag function received 6 parts
(substitution or expressions) instead of 5.
What am I missing here?
Your parts.length
is the length you expected, but notice you're iterating strings
, not parts
. strings.length === parts.length + 1
, so you're accessing parts
out-of-bounds. Iterate parts
instead and append the last string outside the iteration:
function replaceNullData(strings, ...parts) {
var checkedMarkup = "";
parts.forEach((part, index) => {
if (part == null) { // because false, 0, NaN, and '' should be "available"
part = "data not available";
}
checkedMarkup += strings[index] + part;
});
return checkedMarkup + strings[strings.length - 1]; // manually append last string
}