2

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.

johannchopin
  • 13,720
  • 10
  • 55
  • 101
  • could be duplicate of https://stackoverflow.com/questions/12989741/the-property-value-does-not-exist-on-value-of-type-htmlelement – albert Oct 26 '19 at 16:54
  • This is not how you should do it in Angular (no getElementById etc). See this for example: https://stackoverflow.com/questions/35945001/binding-select-element-to-object-in-angular – user3791775 Oct 26 '19 at 17:26

4 Answers4

6

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>
Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
  • 1
    What is the benefit of adding `[value]="item.name"` to this already [existing answer](https://stackoverflow.com/a/58573133/4909087)? Serious question... – cs95 Oct 26 '19 at 18:36
  • 1
    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 – Adrita Sharma Oct 26 '19 at 18:46
2

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.

wentjun
  • 40,384
  • 10
  • 95
  • 107
  • How do we bind [{ 76:{ name: "Bob", age: "27", occupation: "Painter" }, 87: { name: "Barry", age: "35", occupation: "Shop Assistant" }, }]; – Vipul Handa May 23 '21 at 18:50
0

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.

David G.
  • 1,255
  • 9
  • 16
0

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>
cs95
  • 379,657
  • 97
  • 704
  • 746
Timo
  • 138
  • 2
  • 11
  • No point putting this inside a runnable code block as it doesn't recognise angular code. Use a stackblitz session for any demos. – cs95 Oct 26 '19 at 18:16