Introduction
I have created the given partial application in my module:
// GENERIC
const sendEmail = (subject, template) =>
async (to, ...props) => {
const mailsRef = firestore.collection("mails");
const html = template(...props);
const mail = {
to,
message: {
subject,
html,
},
};
await mailsRef.add(mail);
functions.logger.log("Email queued for delivery!");
};
// SPECIFIC
const sendUpdatePasswordEmail = sendEmail(
"Your password has been updated.",
updatePasswordHTMLTemplate
);
const sendSignUpWelcomeEmail = sendEmail(
"Welcome to Binance!",
signUpWelcomeHTMLTemplate
);
const sendBitcoinAddressUpdatedEmail = sendEmail(
"Your bitcoin address has been updated.",
bitcoinWalletAddressHTMLTemplate
);
As you can see, my sendUpdatePasswordEmail
pass a subject and HTML
template generator to the sendEmail
function.
This is how my updatePasswordHTMLTemplate
looks like:
const updatePasswordHTMLTemplate = (language) => `
<!DOCTYPE html>
<html lang="${language}">
...
<body>
<h1>${t("auth.password.update.title", language)}</h1>
</body>
</html>
`;
As you can see, I am internationalizing the emails I send to the final users, using some kind of i18n
.
Problem
The problem I am experiencing is that I need a way to pass, as argument, the user's language to my sendUpdatePasswordEmail
function. And, also, I need to translate the subject of the email:
const sendUpdatePasswordEmail = sendEmail(
"Your password has been updated.", <--- t("auth.password.update.subject", language)
updatePasswordHTMLTemplate
);
Is there any design pattern I should use here? I mean, as you can see, I used the partial application in order to "generalize" my code, making it more readable, but the big problem comes with the subject translation...
This is the way I use the methods I described:
const { email, language } = context.auth.token;
await sendUpdatePasswordEmail(email); // I need to pass the language!
Any ideas? Thank you.
I have thought to do something like:
const sendUpdatePasswordEmail = (language) => sendEmail(
t("subject.scope", language),
updatePasswordTemplate,
language
);
But then, I would have to use the method as follows:
sendUpdatePasswordEmail(language)(emailAddress);
and I don't like it (not a clean way).
CodePudding user response:
I would suggest to simply make the subject
parameter a function accepting a language as well, just like your template
parameter already is:
const makeSendEmail = (subjectTemplate, bodyTemplate) => async (to, ...props) => {
const mailsRef = firestore.collection("mails");
const subject = subjectTemplate(...props);
const html = bodyTemplate(...props);
const mail = {…};
…
};
Then use
const sendUpdatePasswordEmail = makeSendEmail(
(language) => t("subject.scope", language),
updatePasswordTemplate
);
and call
sendUpdatePasswordEmail(emailAddress, language);
as before