I have list of functions to be executed based on the value of a variable, age. These functions correspond to a number of vaccine doses given to an individual.
- If
childern
, then no function (i.e. vaccine) is to be executed. - If
youth
then function firstDose is to be executed. - If
adult
then two functions, firstDose and secondDose is to be executed. - If
old
then three functions, firstDose, secondDose, boosterDose to be executed
Currently, I build this list up manually, with switch and case statements. If the condition is satisfied, then I push the required functions to an array of functions to execute later, like so for old:
vaccines.push(() => this.firstDose(ageVerification))
vaccines.push(() => this.secondDose(ageVerification, previousVaccineCertificate))
vaccines.push(() => this.boosterDose(ageVerification, previousVaccineCertificate, medicalDocuments))
Instead of embedding this in code, I would like to base it on configuration (currently in a file, may move to a database at a later point in time). The constants in a file should look like this:
export const ageVaccineMapping = {
children: null,
youth: [this.firstDose(ageVerification)],
adult:[this.firstDose(ageVerification), this.secondDose(ageVerification, previousVaccineCertificate)],
old:[this.firstDose(ageVerification), this.secondDose(ageVerification, previousVaccineCertificate), this.boosterDose(ageVerification, previousVaccineCertificate, medicalDocuments)],
}
My Question is, How should I create such a file of constants with varying function argument, how do I import constant file in working ts file, and how do I access that function array in code?
I am using Typescript and promise.all to execute. Any leads will be helpful. Anonymous functions are also acceptable.
Please not that, this is just example, this is similar to my use-case. For old people, I want to execute all 3 functions and not just boosterDose function.
Also, I want the constant list should have varying list of function arguments.
CodePudding user response:
Assuming you have this mapping definition in JSON:
{
"groups": {
"children": [],
"youth": ["firstDose"],
"adult": ["firstDose", "secondDose"],
"old": ["firstDose", "secondDose", "boosterDose"]
},
"arguments": {
"firstDose": ["ageVerification"],
"secondDose": ["ageVerification", "previousVaccineCertificate"],
"boosterDose": ["ageVerification", "previousVaccineCertificate", "medicalDocuments"]
}
}
and your person objects look like this:
const people = [
{group: 'adult', ageVerification: 'A1', previousVaccineCertificate: 'B1', medicalDocuments: null},
{group: 'children', ageVerification: null, previousVaccineCertificate: null, medicalDocuments: null},
{group: 'old', ageVerification: 'A3', previousVaccineCertificate: 'B3', medicalDocuments: 'C3'},
{group: 'youth', ageVerification: 'A4', previousVaccineCertificate: null, medicalDocuments: null},
];
Then you could create verification service that maps the property names from the JSON into functions and arguments:
class VerificationService {
mapping;
constructor(mapping) {
this.mapping = mapping;
}
verifyAsync(person) {
const pendingVerifications = this.mapping.groups[person.group].map(funcName => {
const args = this.mapping.arguments[funcName].map(prop => person[prop]);
return this[funcName](...args);
});
return Promise.all(pendingVerifications).then(results => results.every(r => r));
},
firstDose(age) {
console.log('--> verifying firstDose:', [...arguments].join(', '));
return Promise.resolve(true); // simulate async result
},
secondDose(age, previous) {
console.log('--> verifying secondDose:', [...arguments].join(', '));
return Promise.resolve(true); // simulate async result
},
boosterDose(age, previous, medical) {
console.log('--> verifying boosterDose:', [...arguments].join(', '));
return Promise.resolve(true); // simulate async result
}
}
Called like this:
const mapping = JSON.parse('(the above mapping definition)');
const verificationService = new VerificationService(mapping);
people.forEach(async (person) => {
try {
console.log('verifying person', JSON.stringify(person));
const verified = await verificationService.verifyAsync(person);
console.log('result', verified);
} catch (err) {
console.log('verification error', err);
}
});
node.js produces this output:
verifying person {"group":"adult","ageVerification":"A1","previousVaccineCertificate":"B1","medicalDocuments":null}
--> verifying firstDose: A1
--> verifying secondDose: A1, B1
verifying person {"group":"children","ageVerification":null,"previousVaccineCertificate":null,"medicalDocuments":null}
verifying person {"group":"old","ageVerification":"A3","previousVaccineCertificate":"B3","medicalDocuments":"C3"}
--> verifying firstDose: A3
--> verifying secondDose: A3, B3
--> verifying boosterDose: A3, B3, C3
verifying person {"group":"youth","ageVerification":"A4","previousVaccineCertificate":null,"medicalDocuments":null}
--> verifying firstDose: A4
result true
result true
result true
result true
The dummy return Promise.resolve(true);
in the worker functions is async, but it has no delay. With actual asynchronous results, the output will be randomly ordered, but the above serves as a demo only anyway.