4

I having trouble to pass multiple parameters through a callback function. For some reason is one of the objects undefined.

How do i define a callback functions with multiple parameters ?

  public save() {
    let oldStartDate = "2019-01-01";

    let newProject = new Project();
    newProject.oldStartDate = "2018-01-01";

    this.doSomeWork(newProject, this.workFinished_Callback.bind(this), oldStartDate);
  }

  public doSomeWork(project:Project, callback: (updatedProject: Project, ...param: any[]) => any = null, ...callbackArgs: any[]) {
    //Work work..
    console.log(project); //This exists..

    callback.call(project, ...callbackArgs);
  }

  public workFinished_Callback(project:Project, oldStartDate: string) {
    console.log(project); //This is undefined..
    console.log(oldStartDate); //Shows 2018-01-01
  }
2
  • which one of the objects are undefined? Commented Dec 3, 2018 at 9:37
  • 1
    I've wrote comments in the code which object are undefined. Titian below answered and i solved my issue. Thanks for asking ! Commented Dec 3, 2018 at 10:35

1 Answer 1

3

The problem is how you use call. The first argument to call is the this parameter passed to the function, which since you bind the callback will not be accessible in the callback. You can pass null as the first argument and pass the project as the second argument and spread the rest of the arguments as the other arguments:

callback.call(null, project, ...callbackArgs);

A better approach would be to not use call. You can just call the function as you normally would:

callback(project, ...callbackArgs);

You can also build a fully type safe version of your code. In 3.2 bind is correctly typed if you enable strictBindCallApply (read PR). This means that we can use bind and get a correctly typed function. Pair this with tuples in rest parameters (PR) and we can get the compiler to check things fully for us:

class Project { oldStartDate!: string }
type DoSomeworkCallbackArgs<T extends (updatedProject: Project, ...param: any[]) => any> =
    T extends (updatedProject: Project, ...param: infer A) => any ? A : []
class DD {
    public save() {
        let oldStartDate = "2019-01-01";

        let newProject = new Project();
        newProject.oldStartDate = "2018-01-01";

        this.doSomeWork(newProject, this.workFinished_Callback.bind(this), oldStartDate);
        this.doSomeWork(newProject, this.workFinished_Callback.bind(this), 0); //error
    }

    public doSomeWork<T extends null | ((updatedProject: Project, ...param: any[]) => any)>(project: Project, callback: T = null, ...callbackArgs: DoSomeworkCallbackArgs<T>) {
        //Work work..
        console.log(project); //This exists..
        if (callback) callback(project, ...callbackArgs);
    }

    public workFinished_Callback(project: Project, oldStartDate: string) {
        console.log(project); // ok now
        console.log(oldStartDate); //Shows 2018-01-01

    }
}


new DD().save()
Sign up to request clarification or add additional context in comments.

1 Comment

Ah ! Makes sense. Thanks for the type safe verison, i will look into that more.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.