3

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

The Hungry Dictator
  • 3,444
  • 5
  • 37
  • 53
AlvaroAV
  • 10,335
  • 12
  • 60
  • 91

1 Answers1

1

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

AlvaroAV
  • 10,335
  • 12
  • 60
  • 91
  • Please consider this. https://stackoverflow.com/a/41364469/1876572. In your case i think markForCheck is redundant. The model and template is should listen for changes. – Eldho Jan 04 '18 at 09:02
  • @Eldho using `.zone`is better than `markForCheck` ? – AlvaroAV Jan 04 '18 at 10:33
  • 1
    I'm not sure about it. i think its `markForCheck` is good. Might be helpful for you.https://blog.angularindepth.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f – Eldho Jan 04 '18 at 10:47
  • Thanks for the info and the link! I need to spend some hours around Angular 2 lifecycle – AlvaroAV Jan 04 '18 at 12:24
  • Mark if your answer as accepted so others can learn. If your going further include your info here too. – Eldho Jan 04 '18 at 12:26