skid
skid

Reputation: 978

Dynamic function call for service in typescript

I am working on Angular2 project in which i need to generate dynamic function which will be able to call the service provided under the service class. The service class has some 10 get functions as the following.

eg:

my service class

import { Injectable } from '@angular/core';

@Injectable()
export class service {

  constructor() { }

  get function1(){
    return 1;
  }

  get function2(){
    return 2;
  }

  get function2(){
    return 3;
  }
}

I am trying to create a function which take parameter as the function name and return the corresponding answer.

eg:

my app.component.ts

import { Component} from '@angular/core';
import {service} from "./service";

@Component({
      selector: 'app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      providers : [service]
 })

 export class AppComponent(){

  constructor(private _service:service){}

  let one = getVal(function1); /// This should return 1
  let two = getVal(function2); /// this should return 2

  getVal(val){
     return this._service.val; // but i am getting error val not exist on type service
    }

}

Is their any solution for this since it will help me to reduce my code and performance.

Thanks in advance

Upvotes: 8

Views: 21304

Answers (4)

Praveen RL
Praveen RL

Reputation: 698

Add a method to return the corresponding method with switch statement and bind(this).

service.ts

export class DynamicApiCallService {
    constructor(private http: HttpClient) { }

    dynamicMethods(method: string) {
        switch (method) {
            case 'one': return this.one.bind(this);
            case 'two': return this.two.bind(this);
            case 'three': return this.three.bind(this);
        }
    }

    one(id: string) {
        return this.http.get<any>(`one/${id}`);
    }

    two(id: string) {
        return this.http.get<any>(`two/${id}`);
    }

    three(id: string) {
        return this.http.get<any>(`three/${id}`);
    }
}

component.ts

this.dynamicApiCallService.dynamicMethods('one')(id).subscribe(response => {
    console.log(response);
    // Write your logic
})

Upvotes: 0

tmorell
tmorell

Reputation: 559

You can use "any" to bypass the TypeScript strong typing checking.

return (this.service as any)[val]

class Service {
	constructor() {}
	get function1() {
		return 1;
	}
	get function2() {
		return 2;
	}
	get function3() {
		return 3;
	}
}

class AppComponent {
	constructor(private service: Service) {}
	getVal(val: string) {
		return (this.service as any)[val];
	}
}

const service = new Service();
const app = new AppComponent(service);
console.log(app.getVal("function1"));
console.log(app.getVal("function2"));
console.log(app.getVal("function3"));

Upvotes: 2

Estus Flask
Estus Flask

Reputation: 222503

function1, etc are not just 'get functions' - they are property accessor methods.

Instead, it likely should be

let one = getVal('function1');

and

getVal(val){
 return this._service[val];
}

Upvotes: 8

Kenan Banks
Kenan Banks

Reputation: 211980

A little difficult to to tell what you're asking, but this may help.

class MyService {
 get function1() {
   return 1;
 }
  get function2() {
   return 2;
 }
  get function3() {
   return 3;
 }
}

const service = new MyService();

const getValFactory = service => name => service[name];
const getVal = getValFactory(service);

// Use strings, not unquoted function names.
console.log(getVal('function1'));
console.log(getVal('function2'));
console.log(getVal('function3'));

Upvotes: 3

Related Questions