Looping over an array and displaying in dropdown - Angular

So - I have a set of data like so:

people = [
    {
      name: "Bob",
      age: "27",
      occupation: "Painter"
    },
    {
      name: "Barry",
      age: "35",
      occupation: "Shop Assistant"
    },
    {
      name: "Marvin",
      age: "42",
      occupation: "Mechanic"
    },
    {
      name: "Arthur dent",
      age: "27",
      occupation: "Human"
    },

I then also have a drop down in my html like so -

<select id='peeps' name='people'>
    <option></option>    
</select>

<div class='show-info'></div>

This is all in one component and what I am trying to do is loop over the people array, populate the options with their names and when you select that person in the drop down, their information gets displayed in the div. I have tried to start this off but I am running into a few issues.

I started doing this -

peepsSelect = document.getElementById("peeps") as HTMLElement;
populationDropdown() {
  for(var i = 0; i < this.people.length; i++) {
    var option = document.createElement("option");
    option.text = this.people[i].name;
    option.value = this.people[i].name;
    option.value = this.people[i].age;
    option.value = this.people[i].occupation;
    this.peepsSelect.add(option);
 } 
}

However I was getting error messages such as 'add does not exist on type htmlelement.

Try like this:

Working Demo

<select id='peeps' name='people' [(ngModel)]="peepsSelect">
    <option *ngFor="let item of data" [value]="item.name">
      {{item.name}}
    </option>    
</select>

When we declare an array in TypeScript we also tell it what Type of thing the array holds using Type[] or the Array<Type> syntax. We can repeat the same element multiple times in Angular using the NgFor directive

That is not really the Angular way of doing things. You should use two-way data binding to get this done. In addition, you can use ngValue to track the value binded to the option element. Unlike the value binding, ngValue can be used to bind to both string values and objects.

<select [(ngModel)]="selected">
  <option *ngFor="let person of people" [ngValue]="person">{{person.name}}</option>
</select>

<div class='show-info'></div>

And on your component.ts, you will need to define to above properties

export class AppComponent  {
  selected;
  people =[
    {
      name: "Bob",
      age: "27",
      occupation: "Painter"
    },
    {
      name: "Barry",
      age: "35",
      occupation: "Shop Assistant"
    },
    {
      name: "Marvin",
      age: "42",
      occupation: "Mechanic"
    },
    {
      name: "Arthur dent",
      age: "27",
      occupation: "Human"
    }
  ]
}

I have created a demo over here.

KeyValue pipe released in Angular 6.1 to loop through objects,Maps and arrays.Now by passing KeyValue pipe to *ngFor we can loop through objects key values & maps. Prior to this Angular 6.1 release we cannot iterate directly through objects key values & maps using *ngFor directive. To tackle this issue Angular keyvalue pipe has been introduced.

You would need to use appendChild in that case instead. Also, the value of an option is supposed to be unique and only used once in that element as far as I am concerned, so you would be overwriting it in that case; it should be a unique identificator for that person, like an id. Try this instead:

peepsSelect = document.getElementById("peeps") as HTMLElement;
populationDropdown() {
  for(var i = 0; i < this.people.length; i++) {
     var option = document.createElement("option");
     option.text = this.people[i].name;
     option.value = this.people[i].name;
     peepsSelect.appendChild(option);
  } 
}

edit: I just saw Angular in the tags. If this is actually Angular code, you are using Angular wrong.

The collection must be an array or an object. Note: Each instance of the repetition is given its own scope, which consist of the current item. If you have an collection of objects, the ng-repeat directive is perfect for making a HTML table, displaying one table row for each object, and one table data for each object property. See example below.

According to the tag of your question "angular" you should try using *ngFor together with two way binding:

<select [(ngModel)]="selected_peeps">
  <option *ngFor="let people of peoples"
    [attr.data-age]="people.age"
    [attr.data-occupation]="people.occupation">
    {{ people.name }}
  </option>    
</select>

Add logic to loop through datalink. The *ngFor directive (predefined by Angular) lets you loop through data. The following example uses the directive to show all of the values in an array property. To display a list of heroes, begin by adding an array of hero names to the component and redefine myHero to be the first name in the array.

This is an where all the properties are going to live, since your new ngFor loop is going to point to this array, we gotta catch them all. Step 3. Iterate throw all keys, and push each one into

Angular FormArray Example. Angular FormArray is a bit like FormGroup, and it’s used in a very similar way, the difference being that it’s used as an array that envelops around an arbitrary amount of FormControl, FormGroup or even other FormArray instances. FormArray is a class of @angular/forms module.

ngFor iterate over each object in the dataList array and creates a tr for for each object. Add some css style to the app.component.css and you will have the data displayed perfectly in a tabular format. table { width: 100%; border-collapse: collapse; } th { height: 50px; } table, th, td { border: 1px solid black; } ngFor In Angular

Comments
  • could be duplicate of stackoverflow.com/questions/12989741/…
  • This is not how you should do it in Angular (no getElementById etc). See this for example: stackoverflow.com/questions/35945001/…
  • What is the benefit of adding [value]="item.name" to this already existing answer? Serious question...
  • In case he wants to bind value a different on than what is displayed. For example {id:1,name:'Tom'} Name needs to be displayed and id needs to be binded, in this case [value] is important
  • No point putting this inside a runnable code block as it doesn't recognise angular code. Use a stackblitz session for any demos.