2

I want to reference the keyword "this" in a typescript class in my Angular project. But it cannot be used. I always get the error that the variable I want to change is not defined. Here is my implementation:

export class ContactComponent implements OnInit {
  contactForm: FormGroup;
  errorMsg:string = '';
  redirect = "";

  loggedIn(): void {
         this.redirect = "dashboard";
         console.log("success");

in my HTML the redirect variable is connected to a routerLink like this:

<a [routerLink]="redirect"></a>

I have tried this with other variables in other functions but had always the same error.

EDIT:

The loggedIn function is called within another function as "success" parameter like this:

submitForm(): void {
    DBEventProxy.instance().dbevent.login(this.contactForm['username'], 
    this.contactForm['password'], this.loggedIn, this.failed);
  }

The login function needs the parameters username, password, success function, failfunction.

2
  • 2
    how do you call loggedIn method? Commented Jun 24, 2017 at 18:13
  • Edited my question, always forget some necessary information Commented Jun 24, 2017 at 18:17

3 Answers 3

6

You need to bind loggedIn to the correct context. There are several options:

1) define loggedIn as bound function:

export class ContactComponent implements OnInit {
  loggedIn = () = > {
         this.redirect = "dashboard";
         console.log("success");`

2) use bind

export class ContactComponent implements OnInit {
  contactForm: FormGroup;
  errorMsg:string = '';
  redirect = "";

  loggedIn(): void {
         this.redirect = "dashboard";
         console.log("success");

    submitForm(): void {
        DBEventProxy.instance().dbevent.login(this.contactForm['username'], 
        this.contactForm['password'], this.loggedIn.bind(this), this.failed);
                                                    ^^^^^^^^^^
      }

3) wrap this.loggedIn into an arrow function that preserves context like this:

this.contactForm['password'], () => this.loggedIn(), this.failed);

And probably you want to do the same for this.failed. Read more about bind and arrow functions here

Sign up to request clarification or add additional context in comments.

2 Comments

:D I think you have everything wrapped up in this answer a person needs to know about this.
@Boerne, right, thanks) Did you try the first option loggedIn = () = > {?
2

Since you're using Typescript, you can use arrow functions to preserve the context you expect (this will refer to what you want).

In SubmitForm(), replace this.loggedIn with ()=>this.loggedIn(). The same change should be made to this.failed if that's a function.

DBEventProxy.instance().dbevent.login(
    this.contactForm['username'], 
    this.contactForm['password'], 
    ()=>this.loggedIn(), 
    ()=>this.failed()
);

See the Typescript wiki

Red flags for this

The biggest red flag you can keep in mind is the use of a class method without immediately invoking it. Any time you see a class method being referenced without being invoked as part of that same expression, this might be incorrect.

6 Comments

This is not the right solution for my project. When I am changing the this.loggedIn to this.loggedIn() the main function dbevent.login() does not work properly. The incoming JSON messages cannot be read and the login does not work. The bind function works fine!
The this.loggedIn is just a reference of the function as the success parameter of the main function. If I write this.loggedIn() the function will be executed immediately, which is not what I want.
You misread my answer. I didn't ask you to replace with this.loggedIn(). I wrote ()=>this.loggedIn()
@Boerne, what errors did you get with using .bind? I want to understand why bind didn't work. Effectively bind returns the new function that calls this.loggedIn inside through apply, this is almost the same as what ()=>this.loggedIn() does
@Maximus there are no errors within your solution. But if it was impolite to change the 'right' answer I am sorry. But all the given answers were correct and so I thought it was the best to mark the most elegant one (my opinion).
|
1

Instead of just referencing the function, you need to bind this to it: this.loggedIn.bind(this).
Only referencing the function ' strips ' it off the this reference it has when referencing. This is standard Javascript behavior.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.