0

I ran into an issue with Angular 2 using TypeScript that I could use an extra set of eyes on. I am requesting a token from an API which works great. In my response handler I am checking for basic errors and displaying them to the end users. If I log out the error and my message from the console it displays correctly but the view/template does not update.

In my class I have the following:

public message: string;

In my constructor I have:

constructor() {
    this.message = 'Message to enduser';
}

My two methods are the following:

myRequest() {
    (<any>window).privateAPI.getToken({
        token: this.tmpData.token
    }, this.responseHandler);
    return false;
}

responseHandler(response: any) {
    setTimeout(function() {
        if (response.error) {
            // this.message update is not updating in the template
            this.message = response.error.message;
            console.log('error: ', this.message);
        } else {
            // success
        }
    }, 100);
}

Any assistance would be greatly appreciated.

2 Answers 2

1

I was able to solve this issue by utilizing ngZone. The following resolves my problem with my component not updating my template in the API response.

// import NgZone
import {Component, NgZone} from '@angular/core';

// pass NgZone to constructor
constructor(private _zone: NgZone) {
    this.message = 'Message to enduser';
}


requestToken() {
    (<any>window).privateAPI.getToken({
    token: this.tmpData.token
    }, (status: number, response: any) => {
        this._zone.run(() => {
            if (response.error) {
                this.message = response.error.message;
            } else {
              // good to go
            }
        });
    });
}
Sign up to request clarification or add additional context in comments.

Comments

0

This is because you created a new context within setTimeout. The keyword function does this automatically. In TypeScript you can use lambdas (under Lambdas and using this), also called arrow-functions. When using a lambda, it will automatically capture the this available when the function is created rather than when it is invoked.

Try this:

setTimeout(() => {
    if (response.error) {
        // this.message update is not updating in the template
        this.message = response.error.message;
        console.log('error: ', this.message);
    } else {
        // success
    }
}, 100);

6 Comments

That was my initial thought (Hoisting) but when I tried that this.message resulted in undefined Cannot set property 'message' of undefined
You mean to say this is undefined there? I don't know with which context responseHandler has been called from the privateAPI callback...
Yes this in the setTimeout(() => { in the if condition
Thanks Kaj looks like the issue is in the privateAPI callback
use this.responseHandler.bind(this) to make sure the context is right.
|

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.