You Filled the Email Template With replace and the Second {name} Went Out Unfilled
The template was simple. A renewal reminder, written by marketing, with two places for the name. Hi {name}, at the top. We will keep everything ready for you, {name}, near the bottom. The code that filled it was one
The template was simple.
A renewal reminder,
written by marketing,
with two places for the name.
Hi {name},
at the top.
We will keep everything ready for you, {name},
near the bottom.
The code that filled it
was one line per field.
body = body.replace("{name}", customer.firstName);
The test used a template
with one {name} in it.
It passed.
Then the new copy went out
to eleven thousand customers,
and every one of them
was greeted by name
and signed off to as {name}.
In JavaScript,
when the first argument to replace
is a string,
only the first match is replaced.
Not all of them.
The first one,
and then it stops.
It is in the documentation.
It is in nobody's fingers,
because the same word
means something else
almost everywhere else.
Python's str.replace
replaces every occurrence.
Java's String.replace
replaces every occurrence.
So does C#.
So the line read correctly
to everyone who reviewed it.
There are two fixes.
Since ES2021
the language has replaceAll.
body.replaceAll("{name}", customer.firstName)
A string pattern,
every match,
taken literally.
Or a regular expression
with the g flag,
but then the braces
belong to a pattern,
and every special character
in a placeholder
has to be escaped by hand.
replaceAll given a regular expression
without the g
does not quietly do one.
It throws.
That is the kind of failure
you want.
One more trap
waits in the second argument.
The replacement has its own small language.
$& means the matched text.
$$ means a single dollar sign.
So a value with a dollar sign
in the wrong place
can come out changed.
If the text comes from a user,
pass a function instead,
() => value,
and it goes in exactly as written.
Better still,
stop filling templates with replace.
Use a template engine,
something that knows
what a placeholder is
and complains when one is left over.
And add one check
before anything is sent.
If the finished text
still contains a word
inside curly braces,
it does not go out.
Then fix the test.
A template with one placeholder
proves the placeholder works.
A template with the same placeholder twice
proves the code does.
โ Serguey Asael Shinder
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes โ full credit and traffic to the original publisher.