'Angular 5 - Populate Options In mat-select With Objects? Not With NgFor?

NgFor populates a dropdown or list by iterating through an array. However, Observables give us a stream of data, in my case objects, that is already "iterated". Why loop? Just get to work making options.

{skill_id: 8, skill_name: "Whatever"}
{skill_id: 9, skill_name: "Something"}

It seems that I shouldn't need an array when I have such a nice stream of objects that should replace NgFor. I'm thinking something like this and creating a new option as objects are received from the Observable:

<mat-select  placeholder="Select one">
    <mat-option (click)="loadIdValueInForm(skill_id)"
                    [value]="skill_name">{{skill_name}}
    </mat-option>
</mat-select>

There are a variety of older posts that do this in various ways from an array of objects, but it would be better if we could do it with the results of a common Observable setup. Any ideas? Anyone creative about this?

private getListData(dbTable) {
    this.skills$ = this.httpService.getDropDownList(dbTable)
      .map(data => data.resource)
      .switchMap(data => data)


Solution 1:[1]

If you want to iterate over an observable, you can use the async pipe for that.

In your example:

<mat-option (click)="loadIdValueInForm(skill_id)"
                    *ngFor="let skill of skills$ | async"
                    [value]="skill.skill_name">{{skill_name}}
    </mat-option>

Then you can remove the following part from your code:

.map(data => data.resource)

Solution 2:[2]

You're in luck. Java doesn't have 2D or 3D arrays, at all. It only has arrays-of-arrays. The snippet of code you pasted is merely syntax sugar at work.

Thus:

int[][] chessboard = new int[8][];
int row0 = new int[8];
chessboard[0] = row0;

An int[][] is simply a 1D array where each element in your array is, itself, an int[]. See, above, how we make a 1D int array and assign it to the 0 slot of the chessboard variable, thus proving chessboard is 1-dimensional just the same.

Forget about the syntax sugar and make the arrays as above, then you're in full control and can make each 'inner' array whatever size you want it to be. The only weirdness is how to initialize them. new int[8][] is the non-syntax sugar version: That makes a 1D array of int arrays with room for 8 int[], and like all normal array initializes, starts out with 8 null pointers, entirely identical to e.g. String[] x = new String[8], which makes no strings, and after that e.g. x[0] would be null.

You're then free to call chessboard[0] = new int[8], etcetera.

Solution 3:[3]

Java's two-dimensional arrays are array of arrays. When you create a two-dimensional array in Java, it is actually a collection of several one-dimensional arrays. For instance, // read it as create eight 1-D arrays, each with a fixed size of four elements. int[] [] array = new int[8][4] // You could read it as creating eight 1-D arrays, each with an unspecified number of elements. int[] [] array = new int[8][]

In the same way, 3-D arrays are made up of a collection of 2-D arrays.

// You can read it as 3-D array consisting of 2 rows of 2-D arrays with unspecified number of levels 
int[][][] array = new int[3][2][];
// Iterating through the 3-D array 
for (int[][] array2D: array) {
     for (int[] array1D: array2D) {
         for(int element: array1D) {
             System.out.println(element);
         }
     }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TheUnreal
Solution 2 rzwitserloot
Solution 3 Ashwin