Noob
Noob

Reputation: 2807

How do I get values from dynamic number of child components based on another child component action in Angular?

I have this scenario:

I have a parent component that has a child ButtonComponent, and a dynamic number of InputComponents.

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular ' + VERSION.major;

  ids = ['a1', 'b1', 'c1', 'd1', 'g1'] // this part is dynamic

  onSaved(){
    // how do I get all input values here? 
    console.log('saved clicked')
  }
}

app.component.html

<app-button-component (saved)="onSaved()"></app-button-component>
<app-input-component *ngFor="let  id of ids" [id]='id'></app-input-component>

The ButtonComponent has a button, and when that button is clicked, I'd like to get input values from InputComponents components.

button-component.component.ts

export class ButtonComponentComponent implements OnInit {

  @Output() saved = new EventEmitter()

  constructor() { }

  ngOnInit() {
  }

  save(){
    this.saved.emit('true')
  }

}

button-component.component.html

<button (click)="save()" >Save</button>

Now, this is the InputComponent:

input-component.component.ts

 export class InputComponentComponent implements OnInit {

  @Input() id =''
  constructor() { }

  ngOnInit() {
  }

}

input-component.component.html

<div class="inp">
  <span>{{id}}</span>
  <input type="number" min="1" max="100" />
</div>

Now, I understand how to pass the click event from the ButtonComponent to the AppComponent, however, I'm not sure what would be a correct approach regarding getting all input values from the InputComponents on button click.

Here is the StackBlitz.

I'd appreciate your help/suggestions.

Upvotes: 1

Views: 79

Answers (1)

derstauner
derstauner

Reputation: 1796

First, pass a reference variable to the input component:

<app-input-component *ngFor="let  id of ids" [id]='id' #inputComp></app-input-component>

Note, that we don't need unique reference variables for all of the input components, because ngFor does it for us already.

After that we declare the input components like this:

  @ViewChildren('inputComp')
  inputComponents: QueryList<InputComponentComponent>;

In the input component we declare a value variable and bind it to the value of the input element with two way binding:

  <input type="number" min="1" max="100" [(ngModel)]="value" />

Now, we have proper access to the value of each input component and can log it like this:

this.inputComponents.forEach((item) => console.log(item.value));

You can find here the forked example: forked stackblitz

Upvotes: 2

Related Questions