Jan
Jan

Reputation: 79

Angular - passing many different values from child to parent component using the same function

I have a checkbox-component which I'm using in a parent component. When the value has changed, I'm using an @Output() to let the parent component know that the value has been updated.

My code is working but I'm using the checkbox-component many times in my project and I don't want to create it every time new function to set a new value of variable.

Here is the link to my code

My question is: How can I do it better? To prevent creating a new function onRoleChangeCheckboxX() every time I have a new checkbox. My stackblitz is just example, two extra functions doesn't bother me, but what about the case when I have to create 50 checkboxes.

Upvotes: 1

Views: 1290

Answers (3)

rhavelka
rhavelka

Reputation: 2396

Here is a stackblitz of what I think you want? You need to create an array for your checkboxes

  checkboxes = [
    {
      name: 'First checkbox',
      value: false
    },
    {
      name: 'Second checkbox',
      value: false
    },
  ]

Use the *ngFor to have a generic html that you don't need to edit when you add another checkbox to your array

<app-checkbox *ngFor="let box of checkboxes; let i = index" 
              [checkboxName]="box.name" 
              [checkboxData]="box.value"  
              (toggle)="onRoleChangeCheckbox($event, i)"></app-checkbox>

Then your onRoleChangeCheckbox() function can become generic and update your array using an index

  onRoleChangeCheckbox(ev, index) {
    this.checkboxes[index].value = ev;
  }

This method should reduce a lot of your repeated code since you only need to add new checkboxes to an array.

Upvotes: 1

LogicBlower
LogicBlower

Reputation: 1350

May be this is not the better approach but it may work in some cases like this , there will be one emit handler in all cases.

  import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
 
    @Component({

  selector: "app-checkbox",
  templateUrl: "./checkbox.component.html",
  styleUrls: ["./checkbox.component.css"]
})
export class CheckboxComponent implements OnInit {
  @Input() checkboxName;
  @Input() checkboxData:any; 
  @Input() checkBoxLinkedProp:any; // added another property it is the name of the property in the parent component you are updating 
  
  @Output() toggle: EventEmitter<any> = new EventEmitter<any>(); // emit a object instead of bool

  constructor() {}

  ngOnInit() {}

  onToggle() {
    const checkedOption = this.checkboxData;
    this.toggle.emit({checked:checkedOption , checkBoxLinkedProp: this.checkBoxLinkedProp });
  }
}

app.component.html [checkBoxLinkedProp] = "'checkbox1Value'" -- i am passing the prop name as string to child checkbox component. and on toggle a single method is called (toggle)="onRoleChangeCheckbox($event)"

this.toggle.emit will emit object with the back with string prop we passed

<app-checkbox [checkboxName]='checkbox1' [checkboxData]='checkbox1Value' 
  [checkBoxLinkedProp] = "'checkbox1Value'"
 (toggle)="onRoleChangeCheckbox($event)"></app-checkbox>

<app-checkbox [checkboxName]='checkbox2' [checkboxData]='checkbox2Value'  (toggle)="onRoleChangeCheckbox($event)"
[checkBoxLinkedProp] = "'checkbox2Value'"
></app-checkbox>

app.component.ts onRoleChangeCheckbox({checkBoxLinkedProp , checked}) this method will take property name we passed as string from emit event and set that state of class.

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  checkbox1 = 'First checkbox';
  checkbox1Value = false;

  checkbox2 = 'Second checkbox';
  checkbox2Value = false;

  onRoleChangeCheckbox({checkBoxLinkedProp , checked}) {
    this[checkBoxLinkedProp] = checked; // property name that passed to child , is received in this emit event and as this will be set
    console.log(this.checkbox1Value , checkBoxLinkedProp); // tested value for 1st checkbox
  }

}

Upvotes: 1

Rick
Rick

Reputation: 1870

its hard for me to tell exactly what you want, but if you are using eventEmitter & Output, you can Emit a complex json obj with a single emit statement and send as much data as you want to the parent:

@Output() messageEvent = new EventEmitter<any>();

var obj = { check1: true, check2: false, check3: false }
this. messageEvent.emit(obj);

Upvotes: 1

Related Questions