0

The following is my HTML.

            <tr>
                <th>
                    Test Data
                </th>
                <th>
                    Test Data Options
                </th>
            </tr>

            <tr>
                <td>
                    <ng-container>
                       {{data.testData}}
                    </ng-container>
                </td>
                <td class="text-base font-normal">
                    <ng-container>
                        <p-dropdown [options]="dropdownOptions" placeholder="Select Test Data"></p-dropdown>
                    </ng-container>
                </td>
            </tr>

This is my JSON file.

“data”: [ 
          { 
            “testData”: “Test Data A”, 
            “testDataOptions”: [ 
                                 {  
                                   “testDataOptionValue”: “Test Data A1 Option”,     
                                   “testDataOptionLabel”: “Test Data A1” 
                                 }, 
                                 {  
                                   “testDataOptionValue”: “Test Data A2 Option”,     
                                   “testDataOptionLabel”: “Test Data A2” 
                                 } 
                               ], 
          }, 
          { 
            “testData”: “Test Data B”,
            “testDataOptions”: [ 
                                 {  
                                   “testDataOptionValue”: “Test Data B1 Option”,    
                                   “testDataOptionLabel”: “Test Data B1” 
                                 }, 
                                 {  
                                   “testDataOptionValue”: “Test Data B2 Option”,    
                                   “testDataOptionLabel”: “Test Data B2” 
                                 } 
                               ], 
          }

How could I populate the dropdown values in each row in the data table according to their indexes?

For example

The Test Data A row dropdown values should be: Test Data A1, Test Data A2

The Test Data B row dropdown values should be: Test Data B1, Test Data B2

Sample Screen

Nic
  • 127
  • 1
  • 11

2 Answers2

2

I guess you're missing a *ngFor in the code snippet you sent:

<tr *ngFor="let data of json.data">
  <td>{{ data.testData }}</td>
  <td>
    <p-dropdown [options]="data.testDataOptions" optionLabel="testDataOptionLabel" optionValue="testDataOptionValue"></p-dropdown>
  </td>
</tr>

Edit: binding the selected value

A first option, although it might feel hacky depending on context, is to bind to the data object you already have. For instance:

<p-dropdown [options]="data.testDataOptions" optionLabel="testDataOptionLabel" optionValue="testDataOptionValue" [(ngModel)]="data.selectedValue"></p-dropdown>

If that feels weird or you just don't want to mess with that data, then you'll need to store it in a separate variable, which can be an array or a key/value structure. Then you just bind each item to the corresponding entry in the the data structure.

Allan Juan
  • 2,048
  • 1
  • 18
  • 42
  • Hello thank you for the enlightenment what should I be doing if I would want to store the selected option on all the rows since they wouldn't be able to share the same `NgModel` and pass it in a JSON data? – Nic Apr 27 '22 at 11:20
  • You're welcome. I edited my answer with possible solutions for your problem. – Allan Juan Apr 27 '22 at 13:12
  • If the `ngModel` is data.selectedValue does that mean for my original JSON data I need to have a `selectedValue` within the `testDataOptions` so that I can replace it? In the case if I were to use a separate variable such as an array how would I be able to bind each of the data element item into the corresponding entry in the data structure? – Nic Apr 27 '22 at 13:29
  • Get the index of the current element (https://stackoverflow.com/questions/35405618/ngfor-with-index-as-value-in-attribute) and the bind to `selectedValues[i]` – Allan Juan Apr 28 '22 at 14:47
2

Allan gave you the correct answer, I'm just going to expand it a bit. Since your dropdown options list might be a large one, please consider using trackBy as well. It is not mandatory and it does not always prove much more performant, but overall it should help with performance. You can do it like so:

<tr *ngFor="let data of json.data; trackBy: trackByMethod">
  <td>{{ data.testData }}</td>
  <td>
    <p-dropdown [options]="data.testDataOptions" optionLabel="testDataOptionLabel" optionValue="testDataOptionValue"></p-dropdown>
  </td>
</tr>

While in your .ts file (make sure you add some IDs to your items as well - or use other unique identifiers):

trackByMethod = (index: number, item: any): string => item.id;

You can read more about trackBy here: https://dev.to/rfornal/angular-is-trackby-necessary-with-ngfor-594e

watt
  • 799
  • 3
  • 8
  • 22