2

This is similar to redirect to a route after api call in angular2 but I want to use a class variable (this.areaCode) as part of the redirect or update a variable (this.userInfoMessage). Eg:

onSubmit(form: string): void {
    this.taskService.createTask(task).subscribe(this.taskCreated,this.handleError)
}
private taskCreated (resp: any) {
    console.log("Task created successfully",resp)
    this.router.navigate([`/areas/${this.areaCode}`]); // eg: "/areas/12" //"this" is of type SafeSubscriber, not my class
}
private handleError (error: any) {
    this.userInfoMessage="We've got errors here!"  //"this" is of type SafeSubscriber, not my class so the message is now bound
    console.log(error)
}

However I cannot fathom how to get a reference to the class in these functions. Do I need to use the self=this trick. If so, how?

Thanks

UPDATE

I have tried passing this into this.taskService.createTask(task).subscribe(this.taskCreated,this.handleError).bind(this) but Property 'bind' does not exist on type 'Subscription'.

UPDATE (2)

I guess the question is "how do I pass a reference into a subscription callback?"

Having read the linked Q if I want to subscribe passing in a reference to the current object I have tried using

var self= this
this.taskService.createTask(task).subscribe(this.taskCreated(self),this.handleError)

it does not compile. I still have the callback defined as private taskCreated (resp: any)

I don't think this is quite the same as the linked Q.

What am I missing?

Thanks

Badgerspot
  • 2,301
  • 3
  • 28
  • 42
  • Possible duplicate of [How to access the correct \`this\` context inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Estus Flask May 23 '17 at 20:31
  • Before everyone votes to close, could you let me see if I can work out from the other answer what exactly I need to do pleasE? – Badgerspot May 23 '17 at 20:34

2 Answers2

2

You can try this:

private handleError = (error) => {
   this.userInfo = "we have a problem here";
}
Bryan
  • 2,870
  • 24
  • 39
  • 44
Picci
  • 16,775
  • 13
  • 70
  • 113
2

You would need to bind the functions themselves, not the Subscription returned from the subscribe method.

onSubmit(form: string): void {
    this.taskService.createTask(task).subscribe(this.taskCreated.bind(this),this.handleError.bind(this))
}

Another way to do it would be in a closure:

this.taskService.createTask(task)
        .subscribe(
            (res) => this.taskCreated(res),
            (err) => this.handleError
         )
    }

A niftier, cleaner, and less known way to accomplish this in Typescript would be to instantiate the method itself with a fat arrow, leading to a lexical this that always refers to the class itself:

onSubmit(form: string): void {
    this.taskService.createTask(task).subscribe(this.taskCreated,this.handleError)
}

private taskCreated = (resp: any) => {
    console.log("Task created successfully",resp)
    this.router.navigate([`/areas/${this.areaCode}`]); // 'this' will refer to class!
}

private handleError = (error: any) => {
    this.userInfoMessage="We've got errors here!"  // 'this' will also refer to the class!
    console.log(error)
}

The official Typescript docs advise against function binding when possible, so I would use one of the second two solutions.

joh04667
  • 7,159
  • 27
  • 34