angular icon indicating copy to clipboard operation
angular copied to clipboard

There is a problem in updating NgControl when using OnPush strategy

Open Cododoc opened this issue 5 years ago • 6 comments

I have a edit form component with onPush strategy.

In template there is input field:

<input type="text" class="form-control" id="receiveCode" required [maxlength]="25" [(ngModel)]="receiveCode" [ngClass]="setCssValidityClass(receiveCodeCtrl)" #receiveCodeCtrl="ngForm">

By default receiveCode is empty. I update receiveCode in OnActivate method by calling api.

@override
Future<void> onActivate(RouterState previous, RouterState current) async {
  receiveCode = await _receiveAPIService.createNewReceiveCode();
  cdr.markForCheck();
}

I added some debug code to method setCssValidityClass:

Map<String, bool> setCssValidityClass(NgControl control) {
  print('validate: $receiveCode valid is ${control.valid} value = ${control.value}');
  if (control.control != null) {
    print(control.validator(control.control));
  }

  final validityClass = control.valid == true ? 'is-valid' : 'is-invalid';
  return {validityClass: true};
}

After page loaded in console:

receiveCode = ; valid is true; value = null {required: true} receiveCode = 091.05.2019; valid is false; value = {required: true}

On page I see 091.05.2019 in input field and it has is-invalid css class.

I think markForCheck should update value in NgControl.


  • Dart VM version: 2.3.1 (Tue May 21 19:28:38 2019 +0200) on "windows_x64"
  • angular: 5.3.0
  • angular_forms: 2.1.2
  • Chrome

Cododoc avatar May 31 '19 07:05 Cododoc

To be clear, is the control supposed to be valid at this point, but it's not?

I wonder if setCssValidityClass(receiveCodeCtrl) is simply being checked before the control, so it hasn't updated yet. @Cododoc Can you double check if this is the case? Try setting breakpoints in the control and your method to see if they're both updating, just in the wrong order?

@alorenzen @TedSander Any ideas?

leonsenft avatar Jun 03 '19 17:06 leonsenft

@leonsenft , I create example project to show a problem: https://github.com/Cododoc/onpush_example

Yes. Controller has wrong state, when user can see data in input field.

Cododoc avatar Jun 04 '19 12:06 Cododoc

Can you confirm if this is still an issue in 6.0.0-alpha?

We did change NgModel from ComponentState back to a normal directive in that release (it was the only ComponentState directive...), so maybe that changed things here.

alorenzen avatar Jun 04 '19 18:06 alorenzen

That said, NgModel updates it's underlying Control value in ngAfterChanges(), so I would expect that setCssValidityClass() could be called before Control.updateValue().

alorenzen avatar Jun 04 '19 18:06 alorenzen

@alorenzen , there is same behavior on angular 6.0.0-alpha.

Cododoc avatar Jun 05 '19 11:06 Cododoc

Is there any progress?

Cododoc avatar Jun 03 '20 13:06 Cododoc