xtreamsrl / ngx-validation-errors

Angular library to easily show input validation errors
MIT License
39 stars 11 forks source link

Possible Change Detection error? #17

Closed psenechal closed 4 years ago

psenechal commented 4 years ago

Hi Luca,

I haven't been able to figure this one out, and although it doesn't create any problems with the functionality, I'm getting complaints from management and other developers because of the constant console errors.

Whenever a form field with validation is changed, I get an error like this in the console:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'FORMS.DURATION_IN_MONTHS.ERRORS.REQUIRED'. Current value: ''.

The error points back to my CustomErrorsComponent.

I am using ngx-translate for error messages. My AppModule is configured with the validation and translate modules:

NgxValidationErrorsModule.forRoot({ defaultContext: 'CUSTOM_GENERAL', errorComponent: CustomErrorsComponent as any }), TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } })

and I have added the translatePipeFactoryCreator function and providers:

export function translatePipeFactoryCreator(translateService: TranslateService) { return (detector: ChangeDetectorRef) => new TranslatePipe(translateService, detector); }

{ provide: MESSAGES_PIPE_FACTORY_TOKEN, useFactory: translatePipeFactoryCreator, deps: [TranslateService] }, { provide: MESSAGES_PROVIDER, useExisting: TranslateService }

Do you have any ideas on why I might be getting this error in the console? Any help is greatly appreciated. Thanks!

psenechal commented 4 years ago

I downloaded your sample project and ran it locally. I do not see the error that I'm getting, so I updated the project to Angular 9 + Ivy (which is what we're using) and now I get the same error message using your project.

So...the error appears to be related to changes made either from Angular 8-9 or the use of Ivy.

psenechal commented 4 years ago

I disabled Ivy after upgrading your project to Angular 9 and the errors went away. So it seems to be related to Ivy.

rams23 commented 4 years ago

Hi @psenechal sorry for late reply and thanks always for your contribution! I'll try to update to the angular 9 and understand how can i remove that error with ivy. I'll let you know as soon as possibile, sorry it's a busy period

rams23 commented 4 years ago

I update the project to angular 9. here is the branch:https://github.com/xtreamsrl/ngx-validation-errors/tree/feature/angular-9-update. I'm experiencing the issue that you noticed in the bootstrap version, the material one is ok. I'll investigate and come back to you

rams23 commented 4 years ago

Hi @psenechal I updated the library to angular 9. I moved the internal implementation to a statusChange subscription base. It should improve efficency and it seams that the error does not appear anymore. Let me know if it is OK. There are no external breaking changes

psenechal commented 4 years ago

Thanks Luca...I’ll update tomorrow morning and let you know how it goes. The current version seems to work with Angular 10 so I’ll also make sure this new version also works. It doesn’t look like they introduced anything new that would be a breaking change.

psenechal commented 4 years ago

Hi Luca...thanks again for the updated version.

While that appears to have resolved the issue with the ExpressionChangedAfterItHasBeenCheckedError, the form submit directive I created to mark the form fields as touched and dirty no longer works properly.

From what I can tell, the app-custom-errors container isn't being populated with the error when the form fields are marked as touched and dirty by the directive. I have to actually modify the form fields for the app-custom-errors container to get populated with the appropriate error message.

Would you have any ideas for me on how to possibly modify the form submit directive to fix this? Is there anything I can do to mark the form fields as status changed in my directive?

Thank you sir...appreciate the work and the help.

psenechal commented 4 years ago

I was able to get around the issue by setting the value to the existing value which I'm guessing triggers a status change so that the validation directive executes and populates the container:

abstractControl.setValue(abstractControl.value);

It's a bit of a hack, but it gets everything working again for now. Let me know if you have any different suggestions.

rams23 commented 4 years ago

@psenechal Interesting, there isn't a way to listen to touch or dirty. I'll try the solution explained here https://stackoverflow.com/questions/41337024/how-to-observe-touched-event-on-angular-2-ngform that should do the trick so i can update the component silently. I'll work on this tonight

rams23 commented 4 years ago

Hi @psenechal I updated the pachage to v2.1.0 adding the watch of touch and dirty status, I also updated the main example project with your submit directive to validate all fields, and check id everythig works

psenechal commented 4 years ago

Hi Luca, I updated to the new version and removed the "hack" I added to the Form Submit Directive. Everything is working perfectly now. Thanks so much for looking at these issues...the team is really happy about the console errors not appearing any more too. Cheers!