ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51k stars 13.51k forks source link

bug: Angular Reactive Form markAs** not updating Ion-Element #20650

Closed nickwinger closed 4 years ago

nickwinger commented 4 years ago

Bug Report

When calling a markAs (e.g. markAsTouched) on an angular reactive form control the ion class does not update: (e.g. ng-pristine ng-invalid md in-item hydrated ion-untouched ion-pristine ion-invalid ng-touched) (you see that angular puts ng-touched, but ionic still thinks it is ion-untouched...)

Therefore validation is not showing...

Ionic version:

[x] 5.x latest Ionic 5 Version

Current behavior:

The Ion-Input or Ion-Select ignore the angular validation state/classes therefore validation is not working as expected.

Expected behavior:

Ion Elements should align and work like the angular team designed the form validation states.

Steps to reproduce:

Just create a simple angular reactive form with one ion-input and call markAsTouched on that angular control.

Related code: Html: `

No Validation here !
<ion-input [formControl]="inputControl"></ion-input>

`

Typescript: `inputControl: AbstractControl = new FormControl('', Validators.required);

constructor(private activatedRoute: ActivatedRoute) { setTimeout(() => { this.inputControl.markAsTouched(); this.inputControl.markAsDirty(); }, 1000);

}`

insert short code snippets here

Other information:

Ionic info:

insert the output from ionic info here
liamdebeasi commented 4 years ago

Thanks for the issue. It does not look like this is currently possible with Angular Forms. Angular Forms does not emit anything when the pristine/touched states change, so Ionic Framework has no way of updating it programatically.

There is an open feature request for this on the Angular GitHub: https://github.com/angular/angular/issues/10887

Unfortunately, there is not really an ideal workaround. Most of the temporary fixes in the thread involve using undocumented APIs in Angular which can break at any time. The simplest (while not ideal or the most elegant) would be to just remove/add the Ionic classes yourself.

nickwinger commented 4 years ago

Actually you could workaround using a MutationObserver to check for css-class changes, like here: https://dev.to/oleggromov/observing-style-changes---d4f

nickwinger commented 4 years ago

ok, as a workaround i created an angular attribute directive to sync the ionic classes. You can use it by including my library NgSwissArmyKnife: npm i ng-swiss-army-knife --save Then include the module SwissArmyKnifeModule:

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    SwissArmyKnifeModule
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

And put the attribute on your ion-select or ion-input:

<ion-input ngIonSync formControlName="name"></ion-input>
liamdebeasi commented 4 years ago

Hi there,

Can you try the following dev build and let me know if it resolves the issue?

npm i @ionic/angular@5.2.0-dev.202006032038.ebb3f9a

The proper solution to this issue is https://github.com/angular/angular/issues/10887, but we are waiting on the Angular team to implement that. In the mean time, this dev build patches the markAs* methods to manually sync Angular's form classes with Ionic's form classes.

liamdebeasi commented 4 years ago

Thanks for the issue. This has been resolved via https://github.com/ionic-team/ionic/pull/21429, and a fix will be available in an upcoming release of Ionic Framework.

ionitron-bot[bot] commented 4 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.