Populate object values dynamically through function invocations

Currently, I am involved in a project with a VueJS application that incorporates the following helper class and method:

class BiometricMap {
  static get(bioType) {
    if (!bioType) {
      return BiometricMap.default();
    }

    const bioTypes = {
      40: () => this.getFace(),
      41: () => this.getFace(),
      42: () => this.getFace(),
      43: () => this.getFace(),
      60: () => this.getVoice(),
      61: () => this.getVoice(),
      140: () => this.getPin(),
      141: () => this.getPin(),
      150: () => this.getPalm(),
      152: () => this.getPalm(),
    };

    return (bioTypes[bioType])();
  }

  static getFace() {
    return {
      friendly: 'Face',
      type: 'face',
      icon: 'face',
    };
  }

  static getPalm() {
    return {
      friendly: 'Palm',
      type: 'palm',
      icon: 'pan_tool',
    };
  }

  static getPin() {
    return {
      friendly: 'PIN',
      type: 'pin',
      icon: 'radio_button_checked',
    };
  }

  static getVoice() {
    return {
      friendly: 'Voice',
      type: 'voice',
      icon: 'keyboard_voice',
    };
  }

  static default() {
    return {
      friendly: '',
      type: '',
      icon: '',
    };
  }
}

export default BiometricMap;

My goal is to make it dynamic since the list of bioTypes values can vary. Therefore, I made modifications to the get() method as follows:

import BiometricService from '../services/BiometricService';
...

  static async get(bioType) {
    if (!bioType) {
      return BiometricMap.default();
    }

    const bioTypes = {};
    const baseBioTypes = await BiometricService.fetchAll();

    baseBioTypes.data.forEach((type) => {
      // Another instance where we need to change 'passphrase' to 'voice'.
      const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType;
      const methodName = `get${captureType.charAt(0).toUpperCase() + captureType.slice(1)}()`;
      bioTypes[type.bioType] = () => this[methodName];
    });

    return (bioTypes[bioType])();
  }

Despite successfully generating the value for methodName and adding it to the bioTypes object, the problem arises when reaching

return (bioTypes[bioType])();

as it does not trigger the corresponding method (e.g., getFace(), getVoice(), etc.). What adjustments should I make in how I populate the bioTypes object to ensure the correct method is called?

Answer №1

Upon review, it appears that there are a couple of potential errors in this code snippet:

const methodName = `get${captureType.charAt(0).toUpperCase() + captureType.slice(1)}()`;

If captureType is voice, then methodName will be getVoice(). However, it seems unnecessary to have the () at the end.

Additionally, take a look at this section:

bioTypes[type.bioType] = () => this[methodName];

A closer inspection reveals that the function is returning the method instead of invoking it.

To correct these mistakes, you should modify the code to:

bioTypes[type.bioType] = () => this[methodName]();

Here's an updated version with the fixes implemented:

BiometricService = {
  async fetchAll () {
    return {
      data: [
        { bioType: 40, captureType: 'face' },
        { bioType: 41, captureType: 'face' },
        { bioType: 42, captureType: 'face' },
        { bioType: 43, captureType: 'face' },
        { bioType: 60, captureType: 'passphrase' },
        { bioType: 61, captureType: 'passphrase' },
        { bioType: 140, captureType: 'pin' },
        { bioType: 141, captureType: 'pin' },
        { bioType: 150, captureType: 'palm' },
        { bioType: 152, captureType: 'palm' }
      ]
    };
  }
};

class BiometricMap {
  static async get(bioType) {
    if (!bioType) {
      return BiometricMap.default();
    }

    const bioTypes = {};
    const baseBioTypes = await BiometricService.fetchAll();

    baseBioTypes.data.forEach((type) => {
      const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType;
      const methodName = `get${captureType.charAt(0).toUpperCase()}${captureType.slice(1)}`;
      bioTypes[type.bioType] = () => this[methodName]();
    });

    return (bioTypes[bioType])();
  }

  // Other methods omitted for brevity...

}

(async () => {
  console.log('40 :', await BiometricMap.get(40));
  console.log('60 :', await BiometricMap.get(60));
  console.log('140 :', await BiometricMap.get(140));
  console.log('150 :', await BiometricMap.get(150));
})()

It may be worth noting that the current implementation seems inefficient as it loads all bioTypes but only uses one per call. Consider optimizing the code by simplifying the logic as shown below:

static async get(bioType) {
  if (!bioType) {
    return BiometricMap.default();
  }

  const baseBioTypes = await BiometricService.fetchAll();

  for (const type of baseBioTypes.data) {
    if (type.bioType === bioType) {
      const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType
      const methodName = `get${captureType.charAt(0).toUpperCase()}${captureType.slice(1)}`
      return this[methodName]()
    }
  }

  // TODO: Handle fall-through
}

In conclusion, consider revising the approach to retain the object bioTypes if it needs to be reused multiple times, and think about whether creating wrapper functions is necessary for your use case.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Certain public files in Express cannot be accessed locally

While running my Node.js application on localhost, I am able to access http://localhost:3000/css/dashboard.css without any issues. However, when attempting to access http://localhost:3000/css/logo.png for a logo image in the same directory, all I receive i ...

Animating splitting elements with VueJS

I am facing a challenge in creating a split animation with two icons. My goal is to split the icons with some translation in the X-axis after hovering on the container, but it seems like I am missing something in my implementation. The animation does not w ...

Javascript - Could anyone provide a detailed explanation of the functionality of this code snippet?

Ever since joining a new company 9 months ago, I've been encountering this line of code in JavaScript. It seems to work fine and I've been incorporating it into my coding style to align with the previous developers. However, I'm not entirely ...

Capturing AJAX responses within a Chrome Extension

We are currently in the process of developing a Chrome extension to enhance an existing system by simplifying various tasks. This extension will heavily utilize AJAX technology, making it more efficient compared to web scraping or manually triggering even ...

Issue with Jquery AJAX success function specifically in Firefox browser, while other functions in the script are functioning correctly

I have 4 scripts using ajax, but one of them isn't functioning properly in Firefox. Even the alert in success doesn't trigger anything. There are no error messages, just nothing happening. However, it works perfectly fine in IE and Chrome. Belo ...

What could be causing the submission failure of the form post validation?

My Code: <form method="post" name="contact" id="frmContact" action="smail.php"> ... <label for="security" class="smallPercPadTop">Please enter the result:</label> <br /><h3 id="fNum" class="spnSecurity"></h3>& ...

Can a function be passed as props in a scenario where both a Parent and Child component are functional components?

I have a component called ParentComponent where I am trying to pass a function named toggleDrawer to another component called ChildComponent in the following way: const ParentComponent = () { const [drawerState, setDrawerState] = useState(false); ...

Executing a function on the window object in JavaScript

I have come across the following code and am seeking guidance on how to get the last line to function correctly. The API I am using currently employs _view appended as its namespacing convention, but I would prefer to switch to something like arc.view.$f ...

Condition-based React state counter starts updating

In my current project, I have developed the following React component: import React from "react"; import ReactDOM from "react-dom"; import { WidthProvider, Responsive } from "react-grid-layout"; import _ from "lodash"; const ResponsiveReactGridLayout = Wi ...

utilize vuejs to display an alternative route on a side panel

As I develop a back office using Quasar, I am exploring the possibility of creating what I would call a sidepage to open routes. This sidepage would display the requested component without any additional decoration, such as menus. However, there is also a ...

Issues arise with Highcharts Sankey chart failing to display all data when the font size for the series is increased

I am currently working with a simple sankey chart in Highcharts. Everything is functioning correctly with the sample data I have implemented, except for one issue - when I increase the font size of the data labels, not all the data is displayed. The info ...

Generating a collection of items using a pre-existing array of items

Struggling to create an array of objects based on another array of objects. I attempted to use flatMap and then reduce, but encountered an issue when I tried to collect multiple statuses in one object. Below is what I have attempted and the desired result ...

Step-by-step guide on adding data to an arraylist using JavaScript

My ajax callback function receives a json object (arraylist parsed into json in another servlet) as a response, and then iterates through it. Ajax section: $.ajax({ url:'ServiceToFetchDocType', data: {" ...

implement a jQuery loop to dynamically apply css styles

Attempting to utilize a jQuery loop to set a variable that will vary in each iteration through the loop. The plan is for this variable to be assigned to a css property. However, the issue arises where every css property containing the variable ends up with ...

Challenges Encountered when Making Multiple API Requests

I've encountered a puzzling issue with an ngrx effect I developed to fetch data from multiple API calls. Strangely, while some calls return data successfully, others are returning null for no apparent reason. Effect: @Effect() loadMoveList$: Obse ...

To begin, select and upload two files for processing. Once complete, you can download the newly generated

I'm encountering difficulties attempting to upload two files to a php script and have the page download a newly merged file without redirecting to a different page. I do not wish to store any files on the server due to their potential size (2MB) as b ...

Switch up a font style using JavaScript to apply a Google font effect

I am attempting to implement a discreet hidden button on a website that triggers a unique Google font effect for all of the h1 elements displayed on the page. However, I am uncertain about the process and unsure if it is achievable. Below is the code snipp ...

Retrieving the checkbox's status from the database

I have implemented a basic checkbox that updates its state in the database when clicked or unclicked. Is there a way to retain this state and have it displayed as checked if the page is refreshed? Essentially, I want the checkbox to remember its last state ...

Tips for creating an illustration in Vue.js

As I attempt to create an image using canvas, my browser throws this error at me: Uncaught TypeError: Cannot read property 'drawImage' of undefined at Image.img.onload (test.js:23) To troubleshoot, I added some console.log() messages and here ...

Designate material for a particular table header element

Is there a method to pass content within a td-element to a specific th-element? I am working with a dynamic table and need to associate the content correctly under each table header. I have implemented pagination for the rows in the table. Currently, all ...