Reputation: 1927
I have a dynamic reactive form. One part is build by binding the FormGroup and FormControl directives in the Html.In addition -there is a click event for adding other values to the form value programmatically. The problem is that when subscribing to the this.form.valueChanges observable, the callback value (the lambda expression) includes the form value that is being added in the AddToList function, but it is empty, although it had a value before. The valueChanges is being subscribed whenever I change the value in the select control. Can't understand why this is happening.
<form *ngIf="form" >
<div *ngFor="let col of Colomns">
<ul>
<li *ngFor="let val of col.dataList; let i=index">
<span>{{val}}</span>
<a button type="button" (click)="deleteFromList(i, col.field, $event)">
</a>
</li>
</ul>
</div>
<!--below is the part of binding values using the directives-->
<div *ngFor="let col of Colomns; let i = index">
<div [formGroup]="form">
<select [id]="col.field" [formControlName]="col.field" >
<option [value]=''></option>
<option *ngFor="let sys of col.data" [value]="sys.Code">{{sys.Value}}</option>
</select>
<!-- this is a textbox with an AddToList button-->
<div>
<input class="input" [id]="col.field" type="text" #texttosearch>
<button class="btnAddList" (click)="AddToList(texttosearch.value,
col.field, $event)">
</button>
</div>
</div>
</div>
This is the component needed code:
export class dynamicReactiveFrom
{
form: FormGroup;
advanceCols: AdvanceColumnBase<any>[];
constructor(private fb: FormBuilder) { }
initAdvancedSearch(arr:AdvanceColumnBase<any>[])
{
this.advanceCols = arr;
let group: any = {};
arr.forEach(col =>
if (<some condition for the selected Items>)
{
group[col.field] = new FormControl(col.value || '');
}
else/*This is for the items which were added using the AddToList function*/
{
group[col.field] = this.fb.array([this.fb.control('')]);
}
);
this.form = new FormGroup(group);
this.form.valueChanges.subscribe(values => {
/*the value that was set in the AddToList function is now reset, in
the values callback*/
doSeomthing(values);
});
}
AddToList(value: string, field: string, event)
{
event.preventDefault();
let selectedField = this.advanceCols.find( x => x.field === field);
if(selectedField)
{
this.form.value[field] = item.dataList;
}
}
}
The initAdvancedSearch function triggered from outside of the component and has the needed values to populate the form.
Upvotes: 2
Views: 3048
Reputation: 1927
Found where the problem was - I was missing the FormArrayName directive in the ul where the items were added:
<div *ngFor="let col of Colomns">
<ul [formArrayName] = "col.<property with unique value - name or ID>">
<li *ngFor="let val of col.dataList; let i=index">
<span>{{val}}</span>
<a button type="button" (click)="deleteFromList(i, col.field, $event)">
</a>
</li>
</ul>
</div>
and instead of doing:
this.form.value[field] = item.dataList;
I'm doing:
this.form.value[field].push(value);
The problem was that the form.value[field] was referenced by the item.dataList, instead of being managed separately.
Upvotes: 2
Reputation: 3727
Remove the value changes subscription from initAdvancedSearch method and subscribe to it on the OnInit of the component. First implement the OnInit interface:
export class dynamicReactiveFrom implement OnInit
and then provide an implement of ngOnInint:
public ngOnInit() {
this.form.valueChanges.subscribe(values => {
/*the value that was set in the AddToList function is now reset, in
the values callback*/
doSeomthing(values);
});
}
Upvotes: 0