Reputation: 95
I am new to angular and I am trying to implement a reactive form. I will only put a few lines of code so it will be more easy to follow. I have a parent component:
page: number;
ngOnInit() {
this.addProjectForm = this.formBuilder.group({
projectId: ['', Validators.required],
projectName: [''],
startDate: [''],
user: [this.user.email],
country: ['', Validators.required],
projectType: [this.projectTypeValue, Validators.required],
});
this.page = 1;
}
clickNext() {
this.page = this.page + 1;
}
clickBack() {
this.page = this.page - 1;
}
In the parent html I have two child components:
<nb-card>
<nb-card-body id="first-page" *ngIf="page === 1">
<div class="form-group">
<label for="projectType" class="label">Bid / Delivery Product</label>
<nb-select class="select-column" (selectedChange)="saveProjectType();ngOnInit()"
id="projectType" formControlName="projectType">
<nb-option value="bid">Bid</nb-option>
<nb-option value="deliveryProduct">Delivery Product</nb-option>
</nb-select>
</div>
<delivery-template *ngIf="this.addProjectForm.value.projectType == 'deliveryProduct'"
[deliveryProjectForm]="addProjectForm"></delivery-template>
<bid-template *ngIf="this.addProjectForm.value.projectType == 'bid'"
[bidProjectForm]="addProjectForm"></bid-template>
</nb-card-body>
<nb-card-body id="second-page" *ngIf="page === 2">
<!-- some data -->
</nb-card-body>
<nb-card-body id="third-page" *ngIf="page === 3">
<!-- some data -->
</nb-card-body>
<nb-card-footer>
<button nbButton [disabled]="page === 3 || !addProjectForm.valid" class="btn float-left ml-2"
type="button" (click)="clickNext()">Next
</button>
<button nbButton [disabled]="page === 1"
type="button" (click)="clickBack()">Go Back
</button>
<button nbButton [disabled]="page !== 3"
type="submit" (click)="onSubmit()">Save
</button>
</nb-card-footer>
</nb-card>
On the child components (bid-template and delivery template) I am passing the addProjectForm:
// Only showing delivery-template because bid-template is almost the same
@Input() deliveryProjectForm: FormGroup;
ngOnInit() {
if (this.deliveryProjectForm.contains('projectid')) {
this.deliveryProjectForm.setControl('projectid', new FormControl('', Validators.required));
} else {
this.deliveryProjectForm.addControl('projectid', new FormControl('', Validators.required));
}
// same for the rest of the properties
}
// getters
get projectId() {
return this.deliveryProjectForm.get('projectid');
}
// same for the rest of the properties
And on delivery-template html:
<form [formGroup]="deliveryProjectForm">
<div class="col">
<div class="form-group">
<label for="project_id" class="label">Project ID</label>
<input
nbInput id="project_id"
type="text" class="form-control"
placeholder="Project ID"
formControlName="projectid">
<div *ngIf="projectId.invalid && (projectId.dirty || projectId.touched)" class="text-danger">
<small *ngIf="projectId.errors.required">
Project ID is required!
</small>
</div>
</div>
</div>
<!-- Same for the rest of properties -->
</form>
With the form valid and all the fields completed clicking Next and then clicking Back() to the input fields every input field is empty even tough in the debugger addProjectForm has the previous entered values. But the problem is that deliveryProjectForm has empty values after going back. If I am using [hidden] instead of *ngIf the values are restored. Why is this happening?
Thank you.
Upvotes: 0
Views: 1291
Reputation: 1106
When NgIf expression evaluates to false, element it's attached to (in this case component) gets removed from DOM. Then when NgIf expression evaluates to true again, completely new component instance is created. And ngOnInit
is called for this instance. And inside ngOnInit
you reset control values. hidden
attribute doesn't remove element from DOM, that's why control value remains unchanged when using it.
Upvotes: 2