Galactic Ranger
Galactic Ranger

Reputation: 882

Angular 2 with TypeScript: View not updating after setting variable in response handler

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.

Upvotes: 0

Views: 690

Answers (2)

Galactic Ranger
Galactic Ranger

Reputation: 882

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
            }
        });
    });
}

Upvotes: 1

Kaj
Kaj

Reputation: 333

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);

Upvotes: 0

Related Questions