I have a very strange case: After setting up a component containing a form, interacting with the form is incredibly slow. After a click on a dropdown, the form reacts only when the zone.js timeout occurs and the periodic change detection kicks in. Any idea why this could be the case? Why would a component/form be outside of the zone.js change detection? I don't have any errors.
The only debugging input I have is, that on performance profiling in chrome devtools, I get the tap event and then 5-12seconds later, zone.js triggers the UI animation of showing the dropdown options.
In the Chrome DevTools Performance Profiler, this looks like this:
I tap the dropdown around 2 seconds after profiling:
And then 10 seconds later, zone.js, does a periodic update which triggers the dropdown:
Between, nothing happens.
I'm using NgRx and the switch to the component with the form happens in an @Effect, where I call the router.
The Effect looks like this: (It wasn't working with RxJS5 either, so it shouldn't have anything to do with the migration)
@Effect()
placesDetails$ = this.actions$
.ofType<PlaceSelectedAction>(PLACE_SELECTED_ACTION)
.pipe(
switchMap((action: PlaceSelectedAction) =>
this.placesService.loadPlacesDetails(action.payload)
),
map(data => new PlaceDetailsLoadedAction(data)),
tap(_ => this.router.navigate(["/place-details"]))
);
The component itself looks like this:
import { Component } from "@angular/core";
import { Store } from "@ngrx/store";
import { ApplicationState } from "../store/application-state";
import { Router } from "@angular/router";
import { Card } from "../../../../shared/model/card";
@Component({
selector: "app-place-details",
templateUrl: "./place-details.component.html",
styleUrls: ["./place-details.component.scss"]
})
export class PlaceDetailsComponent {
card: Card;
constructor(private store: Store<ApplicationState>, private router: Router) {
this.store.subscribe(state => (this.card = state.cardDataState.card));
}
travelTypeLocation = [
{ value: "city", viewValue: "City" },
{ value: "beach", viewValue: "Beach" },
{ value: "mountains", viewValue: "Mountains" },
{ value: "countryside", viewValue: "Countryside" }
];
travelTypeActivity = [
{ value: "relax", viewValue: "Relax" },
{ value: "sports", viewValue: "Sports" },
{ value: "culture", viewValue: "Culture" },
{ value: "party", viewValue: "Party" }
];
travelTypeCompanions = [
{ value: "family", viewValue: "Family" },
{ value: "partner", viewValue: "Partner" },
{ value: "single", viewValue: "Single" },
{ value: "friends", viewValue: "Friends" },
{ value: "colleagues", viewValue: "Colleagues" }
];
checkPlaceDetails() {
//this.store.dispatch(new PlaceDetailsSubmitAction());
}
goBack() {
this.router.navigate(["/search-places"]);
}
}
And this is the HTML:
<div class="container" fxLayout.xs="column">
<h3>Fill out Place Details</h3>
<form>
<mat-form-field class="full-width">
<input
matInput
placeholder="Title"
type="text"
required
name="title"
[(ngModel)]="card.title">
<mat-error *ngIf="card.title">{{ card.title }}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<input
matInput
placeholder="Description"
type="text"
name="description"
required
[(ngModel)]="card.description"
/>
</mat-form-field>
<mat-form-field class="full-width">
<mat-select
placeholder="Travel Type Location"
name="travelTypeLocation"
required
[(ngModel)]="card.travelTypeLocation"
>
<mat-option *ngFor="let type of travelTypeLocation" [value]="type.value">
{{ type.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="full-width">
<input
matInput
placeholder="Travel Dimension Location (e.g. surfing, biking, museum, theater)"
type="text"
name="travelDimensionLocation"
required
[(ngModel)]="card.travelDimensionLocation"
/>
</mat-form-field>
<mat-form-field class="full-width">
<mat-select
placeholder="Travel Type Activity"
name="travelTypeActivity"
required
[(ngModel)]="card.travelTypeActivity"
>
<mat-option *ngFor="let type of travelTypeActivity" [value]="type.value">
{{ type.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="full-width">
<input
matInput
placeholder="Travel Dimension Activity (e.g. modern city, historic city, hills, high mountains)"
type="text"
name="travelDimensionActivity"
required
[(ngModel)]="card.travelDimensionActivity"
/>
</mat-form-field>
<mat-form-field class="full-width">
<mat-select
placeholder="Travel Companions"
name="travelTypeCompanions"
required
[(ngModel)]="card.travelTypeCompanions"
>
<mat-option *ngFor="let type of travelTypeCompanions" [value]="type.value">
{{ type.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="full-width">
<input
matInput
placeholder="Duration"
type="text"
required
name="duration"
[(ngModel)]="card.averageDuration"
/>
</mat-form-field>
<mat-form-field class="full-width">
<input
matInput
required
placeholder="Cost (€)"
type="number"
name="cost"
[(ngModel)]="card.cost"
/>
</mat-form-field>
<button mat-raised-button color="primary" (click)="checkPlaceDetails()">Add Card</button>
<button mat-raised-button color="secondary" (click)="goBack()">Go Back</button>
</form>
</div>
Please let me know what could be of importance? I'm lost.
Thanks!