Can a function be invoked using a variable as a parameter in JavaScript?

Imagine a scenario where the need arises to use a conditional statement that performs the same action but calls a different method.

const c = true; // just for illustration
let b = '';
if (c) {
  b = 'method1';
} else {
  b = 'method2';
}

function a(){
   this.service.b(filter).subscribe((result) =>{
      // various actions take place
   });
}

Can we utilize the variable b dynamically to invoke a method from the service?

Check out the Stackblitz example

Upon examining the provided example, an updated snippet can be implemented as follows:

if (this.title == 'Students') {
  this.studentService.getStudents().then(results=> this.lists = results);
} else {
  this.studentService.getCandidates().then(results => this.lists = results);
}

However, is there a way to achieve something like this instead:

this.studentService.get[this.title]().then(results=> this.lists = results);

It was mentioned that it may not work in such manner as described above.

Answer №1

In Typescript, you can access a specific method using index access by specifying the type of the index argument. If the type does not have an index signature (which is generally the case with classes), then the index argument must be of type keyof.

class DoStuff {
    messageA() : Promise<string> {
        return new Promise(r=> r("messsageA"));
    }

    messageB() : Promise<string> {
        return new Promise(r=> r("messsageB"));
    }
}

let k: keyof DoStuff = Math.random()> 0.5 ? "messageA" : "messageB";
let o = new DoStuff();
o[k]().then(m=> console.log(m))

If the class has multiple methods with incompatible signatures, calling the result of o[k] may not be possible. To overcome this, you can either explicitly list the methods you want to index (`let k: "messageA" | "messageB"`). Alternatively, you can use a type that filters the keys:

class DoStuff {
    messageA() : Promise<string> {
        return new Promise(r=> r("messsageA"));
    }

    messageB() : Promise<string> {
        return new Promise(r=> r("messsageB"));
    }
    util(): string { return ""}
}

let k: keyof DoStuff = (Math.random()> 0.5 ?"messageA" : "messageB") as keyof DoStuff;
let o = new DoStuff();
o[k]().then(m=> console.log(m)) //error

type FilterKeysByType<T, V> = { [P in keyof T] : T[P] extends V ? P : never}[keyof T]
let kok:FilterKeysByType<DoStuff, ()=> Promise<string>>  =  (Math.random()> 0.5 ?"messageA" : "messageB") as FilterKeysByType<DoStuff, ()=> Promise<string>>;
o[kok]().then(m=> console.log(m)) //error

Answer №2

A valid alternative to storing a function as a string is assigning the function directly to a variable, like this:

function bla() {
  console.log('bla');
}
let b = bla;
b();

Some users may disagree with this approach, so let me explain further. When calling b on this.service, the method described above won't work.

In objects, functions are attached using their name as the key. Therefore, it's recommended to use strings in such cases. Here's an example:

let thing = {};
thing.a = function() {}
let b = 'a';
thing[b]();

The same principle applies if your object is a class, like so:

class Thing {
 bla() {}
}
let a = new Thing();
let b = "bla";
a[b]();

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

You are not able to access the instance member in Jest

My first encounter with Javascript has left me puzzled by an error I can't seem to figure out. I'm attempting to extract functions from my class module in order to use them for testing purposes, but they remain inaccessible and the reason eludes ...

Encountering an 'Unexpected token u in JSON at position 0' error while utilizing the scan function in Amazon

I'm currently working on a Lambda function that is connected to an API. While most of the routes are functioning properly, I'm encountering an issue with the GET /items route which is supposed to retrieve all items from a DynamoDB table. Unfortun ...

What is the process for invoking a websocket from an HTML client?

I have created a WCF Service using netHttpBinding binding and it is hosted on IIS 8 (Windows Server 2012). The interfaces for the service are as follows: [ServiceContract(CallbackContract = typeof(IDuplexCallbackContract))] public interface IHelloWebSocke ...

Experiencing a problem when switching between various divs on the website

Having difficulties with tracking the state of my application. Whenever I select a ticket on the edit form, the updated information is passed to all other tickets. I suspect there is an issue with how the state is being managed. The problematic function s ...

Necessary CSS selector input equivalent in Reactive Forms

Is there a similar CSS method like input:required {CSS} to style all the reactive form fields in Angular that are set as required using Validators.required in their formControl? Or is there another approach to achieve this with CSS? ...

Unable to utilize angular-local-storage

Here is the code snippet I'm working with: angular.module('MyModule').controller('MyController', ['$scope', '$stateParams','$location', '$http','LocalStorageModule', function($s ...

Bringing a JavaScript file into an Ionic/Angular 2 project

I have been attempting to integrate a simple JS library into Angular 2. The library in question is JIC.js. var jic = { /** * This function takes an Image Object (JPG or PNG) and returns a compressed new Image Object * @param {Ima ...

Traverse through an array or object using recursive render functions in JavaScript

Here is an example of the issue I am currently trying to solve: https://codepen.io/wombsplitter/pen/KyWKod This is the structure of my array: [{ //obj 1 link: [{ //obj 2 link: [{ //obj 3 }] }] }] The ...

The correct value is not being received by the AJAX POST

I am facing an issue where the $_POST variable in PHP is getting assigned 'undefined' when I try to post the value of a selected radio button. How can I make sure that the correct value is assigned to the $_POST variable? I have tried using URIen ...

Steps for setting up Node.js or npm on XAMPP

Hello there, I'm new to all of this so please bear with me if I make any mistakes. As a beginner developer, I am currently working on developing a web application locally using XAMPP. My plan is to eventually deploy it using a hosted web service. XAM ...

The link that has been clicked on should remain in an active state

Is there a way to make the link that is clicked on active? I have attempted various scripts but have had no luck in getting the desired effect. Can anyone identify what might be causing the issue? $("a").click(function () { if ($(this).hasClass("acti ...

Difficulty switching back and forth between three varying heights

I have a container with a button labeled "Show more". Upon clicking the button, the height of the container will transition through 3 different states. <div class="segment-suggestion-content height-small"> <div class="segment-suggestion-sh ...

Tips for ensuring that the dynamic view updates correctly when the scope variable is modified

I am currently working on an Angular SPA where a $scope variable plays a crucial role in determining the content of a specific page. When a user clicks on a different link in the menu, parameters are passed through the URL, updating the scope variable. How ...

Is it possible for React props to include bespoke classes?

In our code, we have a TypeScript class that handles a variety of parameters including type, default/min/max values, and descriptions. This class is utilized in multiple parts of our application. As we switch to using React for our GUI development, one of ...

Create HTML content on the fly and ensure its validity

I am attempting to dynamically add a TextBox with the ID "tbComment" when the selected date is less than the current date on the client side, prior to hitting the submit button. Which approach would be the most effective in achieving this? I have tried us ...

Obtain the Angular 2 Form object within a TypeScript class file for manual configuration of form properties

I have a form inside a PrimeNG dialog control. I need to handle two different submit methods based on certain conditions for this form, so I don't want to use the ngSubmit method in the form tag. Instead, I want to manually access the form object in m ...

Guide to Including Captions and Spans in a Table

In the given HTML code, nested tables are used by the developer which cannot be changed. However, there is a requirement to replace the table class and add a caption and span only to the main table. <table class="two_column_layout" align="center"> & ...

The client-side validation in JavaScript seems to be malfunctioning

I am facing an issue with client-side validation on a login page I designed. Despite writing JavaScript code for validation, the email extension acceptance is not functioning properly. Specifically, I want to restrict email addresses to only those with the ...

Angular input range slider that automatically rounds decimal values from the data bindings

I've implemented a range slider within an Angular form to capture and display recorded values. <input [formControlName]="object.id" [id]="object.id" type="range" [(ngModel)]="object.answer" [step]="objec ...

A specialized React hook designed for fetching data in a continuous loop

Been struggling with this issue for hours :( I have a hook called useCollection which is designed to provide data retrieved from my API and updated in real-time using a websocket. It works perfectly for real-time updates, but I want it to also update the ...