javascript - Angular: pass a method as parameter - Stack Overflow

I have these two methods which are almost similar:private firstFunction () {this.serviceOne.methodOne()

I have these two methods which are almost similar:

private firstFunction () {
    this.serviceOne.methodOne().subscribe(
      res => {
        return  resultOne = res;
      },
      err => {}
    );
  }

private secondFunction () {
    this.serviceTwo.methodTwo().subscribe(
      res => {
        return  resultTwo = res;
      },
      err => {}
    );
  }

I want to write a generic function, like this:

genericFunction (service ,method , result  ) {
        service.method().subscribe(
          res => {
            return  result = res;
          },
          err => {}
        );
      }

And consequently I want to get something like this working:

genericFunction (serviceOne , methodOne , resultOne );
genericFunction (serviceTwo , methodTwo , resultTwo );

Actually, I cannot find how to pass methodOne and methodTwo as params. Any sugestions?

I have these two methods which are almost similar:

private firstFunction () {
    this.serviceOne.methodOne().subscribe(
      res => {
        return  resultOne = res;
      },
      err => {}
    );
  }

private secondFunction () {
    this.serviceTwo.methodTwo().subscribe(
      res => {
        return  resultTwo = res;
      },
      err => {}
    );
  }

I want to write a generic function, like this:

genericFunction (service ,method , result  ) {
        service.method().subscribe(
          res => {
            return  result = res;
          },
          err => {}
        );
      }

And consequently I want to get something like this working:

genericFunction (serviceOne , methodOne , resultOne );
genericFunction (serviceTwo , methodTwo , resultTwo );

Actually, I cannot find how to pass methodOne and methodTwo as params. Any sugestions?

Share Improve this question edited Sep 18, 2018 at 14:13 David Walschots 12.7k5 gold badges38 silver badges59 bronze badges asked Sep 18, 2018 at 14:10 firasKoubaafirasKoubaa 6,87729 gold badges87 silver badges163 bronze badges 2
  • Is this what you are looking for ? stackoverflow./questions/14638990/… – Titian Cernicova-Dragomir Commented Sep 18, 2018 at 14:12
  • Are you sure you're not falling into the trap of trying to return a value from an async method? – Jamiec Commented Sep 18, 2018 at 14:18
Add a ment  | 

2 Answers 2

Reset to default 1

There are several issues in your code.

Firstly, you want to modify the field you pass in as a parameter (as suggested by result = res. You can't pass in a reference to a field, but you can pass in the field name, and use indexing to change the field. keyof T will allow you to pass in the field in a type safe way.

Secondly if you want to access a method on a service. Again we can do this passing in the method name, and we can constrain the service to have a method with the passed in method name, that returns an Observable. The result of the Observable can also be constrained to be of the same type of the field we are going to assign it to in order for the method to be fully type safe.

declare class Service1 {
    method1() : Observable<number>
}
declare class Service2 {
    method2() : Observable<string>
}
class MyClass {
    resultOne!: number;
    resultTwo!: string;

    constructor() {
        this.genericFunction(new Service1(), "method1", "resultOne");
        this.genericFunction(new Service2(), "method2", "resultTwo");
        this.genericFunction(new Service1(), "method1", "resultTwo"); // error resultTwo is a string, the method return Observable<number>
        this.genericFunction(new Service2(), "method", "resultTwo"); // error method does not exit on Service2
        this.genericFunction(new Service2(), "method2", "resultTwo2"); // error field does not exist on type 
    }

    genericFunction<MethodKey extends string,  ResultKey  extends keyof MyClass>(service:Record<MethodKey, ()=> Observable<MyClass[ResultKey]>>, method:MethodKey, result: ResultKey){
        service[method]().subscribe(
            res => this[result] = res,
            err => {}
        );
    }
}

Note We could have also passed in the function as a function not just as a name, but directly a typed function. The disadvantage of this is that we either have to use bind to ensure the service method will still have the correct this when it's called, or use an arrow function when calling (again to ensure the service method has the correct this). This is error prone though, bind results in an untyped function, so we can't check patibility to the field, and someone might pass service.method directly and no error would be reported until runtime:

class MyClass {
    resultOne!: number;
    resultTwo!: string;

    constructor() {
        var service1 = new Service1()
        var service2 = new Service2()
        this.genericFunction(()=> service1.method1(), "resultOne");
        this.genericFunction(()=> service2.method2(), "resultTwo");

        this.genericFunction(service2.method2, "resultTwo"); // no error, depending on the implementation of method2 it might or might not work
        this.genericFunction(service2.method2.bind(service2), "resultOne"); // no error, the service call will work, but we store it in an inpatible variable
        this.genericFunction(()=> service1.method1(), "resultTwo");// error resultTwo is a string, the method return Observable<number>
        this.genericFunction(()=> service2.method2(), "resultTwo2");// // error field does not exist on type 
    }

    genericFunction<MethodKey extends string,  ResultKey  extends keyof MyClass>(method:()=> Observable<MyClass[ResultKey]>, result: ResultKey){
        method().subscribe(
            res => this[result] = res,
            err => {}
        );
    }
}

try by using the following code:

private firstFunction () {
    let response= genericFunction(this.serviceOne.methodOne())      
}
private secondFunction () {
   let response = genericFunction(this.serviceTwo.methodTwo())    
}

Modify you Generic Function by just receiving a variable.

//if it is angular 4 or less
genericFunction (method: Observable) {
        return method.map(res => {
           return res.json();
        });
      }
 //if it is angular 5 or 6
 genericFunction (method: Observable) {
        return method.pipe(            
           map(res => {
           return res;
        }));
      }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742405415a4437746.html

相关推荐

  • javascript - Angular: pass a method as parameter - Stack Overflow

    I have these two methods which are almost similar:private firstFunction () {this.serviceOne.methodOne()

    9小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信