4

I really an imported 3rd party script to trigger a function like show_end_screen (below)

my component

import { Router } from '@angular/router';
import { init_game, start_game, stop_game } from '../../assets/js/game';

@Component({})

export class PlayComponent implements OnInit {
    constructor(public router:Router) {}
    ngOnInit() {
        init_game(this.show_end_screen) // load ready
    }
    show_end_screen(data){
        console.log(data) //this works
        this.router.navigate(['play']); //"this" is undefined
    }
}

init_game(this.show_end_screen) <== Here I am passing show_end_screen to the imported script. when the 3rd party script runs show_end_screen(data) I successfully log data to the console. But i dont have access to this or any other reference to angular

this.router.navigate(['play']); <== here i get a console error

ERROR TypeError: Cannot read property 'nav' of undefined

4

3 Answers 3

6

When you pass a class-bound method as a value it loses the context (this). You can bind explicitly or call within the callback:

ngOnInit() {
  // explicit binding
  init_game(this.show_end_screen.bind(this));

  // lexical binding
  init_game(data => this.show_end_screen(data));
}

You can also use an instance-bound method for your component instead.

show_end_screen = (data) => {
  this.router.navigate(['play']);
}
Sign up to request clarification or add additional context in comments.

2 Comments

so glad to have your help! .bind(this) ... will that change how the callback is used in the other script?
I dont understand how it works but It did... Need to study up... Thanks!
0

This is because this refers to the calling context, not the context from which you assign your callback. You should be able to make this work, by explicitly defining which context this refers to by using the bind function.

So your code would look like this:

ngOnInit() {
    init_game(this.show_end_screen.bind(this))
}

Comments

0

I'm assuming this.router is defined in your constructor

In addition to @Explossion Pills answer, you could define your method as a property and save that bind() call

show_end_screen = (data) => {
  console.log(data) //this works
  this.router.navigate(['play']); //"this" is undefined
}

Comments

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.