Home > Software design >  Create a list of functions to be executed from constant file in node.js
Create a list of functions to be executed from constant file in node.js

Time:10-21

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.

  • Related