Angular 2: [Ngclass] and [Disabled] Not Updating Dynamically

Angular 2: [Ngclass] and [Disabled] Not Updating Dynamically

I'm using these angular versions:

@angular/animations: 4.4.6
@angular/common: 4.4.6
@angular/compiler: 4.4.6
@angular/core: 4.4.6
@angular/forms: 4.4.6
@angular/http: 4.4.6
@angular/platform-browser: 4.4.6
@angular/platform-browser-dynamic: 4.4.6
@angular/router: 4.4.6
@angular/cli: 1.4.9
@angular/compiler-cli: 4.4.6
@angular/language-service: 4.4.6
typescript: 2.3.4

And I have this problem, I have a button like this:

<button 
    [disabled]="submitted || !form.valid" 
    class="btn btn-block btn-hero-success"
    [ngClass]="{'btn-pulse': submitted}">
          Sign In
</button>

And my problem is when I update the variable submitted on the controller, it doesn't get updated on the template unless I click one input.

This is a small summary of my current controller:

export class NbLoginComponent {
  errors: string[] = [];
  messages: string[] = [];
  user: any = {};
  submitted: boolean = false;
  @ViewChild('form') form;

  constructor(protected service: NbAuthService,
              @Inject(NB_AUTH_OPTIONS_TOKEN) protected config = {},
              protected router: Router) {
   ....
   ....
  }

  login(): void {
    this.errors = this.messages = [];
    this.submitted = true;

    this.service.authenticate(this.provider, this.user).subscribe((result: NbAuthResult) => {
      this.submitted = false; // <-- I updated submitted variable here
      ...
    });
  }

}

I'm customizing nebular package authentication but the problem it is with some lack of understanding from my part of Angular 2.

My questions are:

  • Why the variable submitted is not updated on the template as soon as I change it on the controller ?

  • Why the variable gets updated if I make click on any form input ?

When I try to login, until the response is back, the button gets disabled and also a class is added so the button "blinks".

The problem is that neither the class nor the disabled property gets updated because the variable submitted only gets updated if I click on any input form and then outisde the input

I need to know if I'm linking the variables in a wrong way, or I need to trigger something similar to $scope.apply.

I tried to use ApplicationRef.tick() after the variable submitted it's updated but nothing happened

1 Answer

I solved the issue adding this 3 lines to my code:

// Import ChangeDetectorRef
import { ChangeDetectorRef } from '@angular/core';

// Add ChangeDetectorRef to constructor
constructor(private cd: ChangeDetectorRef) {}

// Call markForCheck at the end of the subscribe function
this.cd.markForCheck();

My component ended like

import { ChangeDetectorRef } from '@angular/core';  // <---

export class NbLoginComponent {
  errors: string[] = [];
  messages: string[] = [];
  user: any = {};
  submitted: boolean = false;
  @ViewChild('form') form;

  constructor(
       private cd: ChangeDetectorRef, // <-----
       protected service: NbAuthService,
       @Inject(NB_AUTH_OPTIONS_TOKEN) protected config = {},
      protected router: Router) {
   ....
   ....
  }

  login(): void {
    this.errors = this.messages = [];
    this.submitted = true;

    this.service.authenticate(this.provider, this.user).subscribe((result: NbAuthResult) => {
      this.submitted = false;
      this.cd.markForCheck(); // <----
    });
  }

}

After calling this.cd.markForCheck(); at the end of the subscribe method, the HTML is updated correctly

5

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross
Author

Alexander Ross

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.