Friday, May 10, 2024
 Popular · Latest · Hot · Upcoming
68
rated 0 times [  70] [ 2]  / answers: 1 / hits: 23229  / 7 Years ago, mon, september 11, 2017, 12:00:00

I have two arrays of data: AssociatedPrincipals (previously saved data) and ReferencePrincipals (static data to populate in dropdown controls). I'm struggling to get the previous value from AssociatedPrincipals to be displayed/selected in a dynamic amount (most examples use a single dropdown) of dropdowns on page load.



I'm not certain how to set up the form (code behind and HTML), especially setting the Select's formControlName. Currently, the static values in each dropdown populate, but I cannot get the selected value to bind properly.



public ngOnInit() {
this.factsForm = this.formbuilder.group({
associatedPrincipals: this.formbuilder.array([]),
referencePrincipals: this.formbuilder.array([])
});

// Data for both of these methods comes from external source...
var responseData = // HTTP source...
// Push retrieved data into form
this.initPrincipals(responseData[0]);
// Push static data into form
this.initStaticData(responseData[1]);
}

public initPrincipals(principals?: IAssociatedPrincipal[]): FormArray {
principals.forEach((principal) => {
this.associatedPrincipals.push(this.createPrincipalFormGroup(principal));
});
}

public initStaticData(response: IReferencePrincipal[]) {
response.forEach((principal) => {
this.referencePrincipals.push(
this.formbuilder.control({
code: principal.code,
canHaveLead: principal.canHaveLead,
isDuplicate: false
}));
});
}

public createPrincipalFormGroup(principal: IAssociatedPrincipal) {
return this.formbuilder.group({
code: principal.code,
canHaveLead: false,
isDuplicate: false
});
}

public get associatedPrincipals(): FormArray {
return this.factsForm.get('associatedPrincipals') as FormArray;
}

public get referencePrincipals(): FormArray {
return this.factsForm.get(referencePrincipals) as FormArray;
}


HTML:



 <form novalidate [formGroup]=factsForm>
<div formArrayName=associatedPrincipals>
<div *ngFor=let associatedPrincipal of associatedPrincipals.controls; let i=index; [formGroupName]=i >
<select class=form-control create-input
formControlName=i>
<option value=null disabled selected hidden>--Select--</option>
<option *ngFor=let refPrincipal of referencePrincipals.controls [ngValue]=refPrincipal>refPrincipal.value.code</option>
</select>
</div>
</div>
</form>


I appreciate any feedback!



EDIT: Added Plunker showing the issue: https://embed.plnkr.co/XMLvFUbuc32EStLylDGO/


More From » angular

 Answers
133

Problems in your demo



Based on the demo you provided, There are several problems as listed below:




  • There is no formControlName assigned to select.

  • You are binding object to select's option.



For the first problem



Since you are looping through associatedPrincipals to show dropdownlist dynamically. And associatedPrincipals which is a formArray which can consider as below:



associatedPrincipals = {
0: FormControl,
1: FormControl
}


So you can simply assign i which is defined at *ngFor expression to formControlName.



<select formControlName={{i}} style=margin-top: 10px>
...
</select>


For the second problem



While binding object to option, Angular will compare default value and option's value by object instance by default.



You can set same instance(get from value of referencePrincipals's formControls) to formControl of associatedPrincipals(as @Fetra R.'s answer). But this is not the most convenient way since you have to take some logic to keep the same instance of an object.



Here I would give you another solution which is using compareWith directive designed specifically for your current situation, see docs.



Using compareWith directive, you just need to implement a compareFun to tell angular how to consider two objects(with different instances) as the same.Here yo can include comparing object instance and comparing object fields at the same time.



<select formControlName={{i}} style=margin-top: 10px [compareWith]=compareFun>
<option value=null disabled selected hidden>--Select--</option>
<option *ngFor=let refPrincipal of referencePrincipals.controls
[ngValue]=refPrincipal.value>{{ refPrincipal.value.code }}</option>
</select>

// tell angular how to compare two objects
compareFn(item1, item2): boolean {
return item1 && item2 ? item1.code === item2.code : item1 === item2;
}


Refer docs and fixed demo to learn detail about it.


[#56511] Friday, September 8, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tayaw

Total Points: 749
Total Questions: 88
Total Answers: 86

Location: Djibouti
Member since Sun, Feb 27, 2022
2 Years ago
tayaw questions
;