I have two string arrays on my backend that I have to fill with either a single string or multiple strings. However they are not key value pairs. I am trying to push a string into one of the arrays but an running into the fact that I do not and cannot specify a control: value pair.
my formArray looks like
collections: new FormArray([]),
my html to select the strings
<md-select placeholder="Collection">
<md-option (click)="addCollectionId('one')" value="Local">Local</md-option>
<md-option (click)="addCollectionId('two')" value="Music">Music</md-option>
<md-option (click)="addCollectionId('three')" value="Performing Arts">Performing Arts</md-option>
<md-option (click)="addCollectionId('four')" value="Sports">Sports</md-option>
<md-option (click)="addCollectionId('five')" value="Restaurants">Restaurants</md-option>
</md-select>
and my logic to add the strings to the formArray looks like:
addCollectionId(id: string) {
const control = <FormArray>this.createCardForm.controls['collections'];
control.push(id);
}
I am getting the error 'Argument of type 'string' is not assignable to parameter of type 'AbstractControl'.
Since I cannot push a control: value pair and only string/strings how can I push strings to the array while still staying in my overall form?
Any help/tips/suggestions would be much appreciated.
You can use Reactive Forms API to achieve this, also I recommend to use angular formBuilder:
export class SelectOverviewExample {
createCardForm: FormGroup;
foods = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
// inject form builder
constructor(private fb: FormBuilder) {
// add collections form array to your form
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
});
}
// function which pushed new value to collections array
addCollectionId(val) {
const collections = this.createCardForm.get('collections');
// add only once
if (!collections.value.includes(val)) {
collections.push(this.fb.control(val));
}
}
}
this way all your selected values will be added to the form and will be available under createCardForm.value.collections
array.
here is HTML:
<md-select placeholder="Favorite food">
<md-option [disabled]="createCardForm.value.collections.includes(food.value)"
*ngFor="let food of foods"
[value]="food.value"
(click)="addCollectionId(food.value)">
{{ food.viewValue }}
</md-option>
</md-select>
<pre>{{ createCardForm.value | json }}</pre>
here is updated plunker forked from https://material.angular.io/components/select/overview
here is reactive form only solution, without call to addCollectionId()
function.
Add reactiveCollections field to the form group:
constructor(private fb: FormBuilder) {
this.createCardForm = this.fb.group({
collections: this.fb.array([]),
reactiveCollections: null
});
}
Add form group and control names to the md-select
:
<form [formGroup]="createCardForm">
<md-select placeholder="Favorite food"
multiple="true"
formControlName="reactiveCollections">
<md-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</md-option>
</md-select>
</form>
Plunker is updated as well