Search code examples
angularmodal-dialogngx-bootstrapviewchild

Angular 4, sending data from parent to child component issue


Hellou, can someone explain to me how to make this work properly, because I'm not very experienced in using viewChild directives...

Here's the deal, I'm working on a small crud app in angular, and have a populated table with my data, on each row I have a delete button which opens up a small confirm window I've managed to get modal(ngx-bootstrap 3) to open on click, now I have to figure out how to call function from my parent component, my http requests work with button on my table, but not when I try to modify it to open a modal and make a delete request clicking on confirm button...

Here's some code, in my parent app.component.html small table...

     <table style="width:100%" class="table table-striped" 
      id="billing_history_table">
     <thead class="head">
        <tr>
            <th>Name</th>
            <th></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let e of employeelist>
            <td>{{e.firstName}}</td>
            <td><a (click)="childModal.show()"><span class="glyphicon 
      glyphicon-trash"></span></a></td>
        </tr>
       </tbody>
      </table>

     <app-modal-component #childModal>

     </app-modal-component>

In my app.component.ts which is my parent component

    @ViewChild('childModal') childModal: ModalComponent;

This is the function I want to call in my opened modal, from parent comp.

        DeleteEmployee(id: string) {
        this._usermanagementservice.deleteEmployee(id).subscribe(res => {
            this.LoadAllEmployees();
        })
        }

Id is from my DB, not shown in the table, I don't know how to pass it to modal

In child component I have

  @ViewChild('childModal') public childModal: ModalDirective;

   show() {
    this.childModal.show();
   }
   hide() {
    this.childModal.hide();
  }

And in child component .html

    <div bsModal #childModal="bs-modal" class="modal fade" tabindex="-1" 
    role="dialog" [config]="{backdrop: 'static'}" aria-hidden="true">
    <div class="modal-dialog modal-sm">
    <div class="modal-content">
        <div class="modal-body text-center">
            <p>Do you want to confirm?</p>
            <button type="button" class="btn btn-default" 
    (click)="confirm()">Yes</button>
            <button type="button" class="btn btn-primary" 
    (click)="hide()">No</button>
        </div> 
        </div>
     </div>
   </div>

Hopefully, you understand my question, confirm button in child .html should trigger DeleteEmployee function and using Id from my table make delete request... I know It has to do something with output and event emiters, but I've got no clue, thanks :(


Solution

  • You can use as EventEmitter and Input() in Angular for this task.

    In your child component declare two event emitters one for yes click and one for no click. You can use an Input to pass the Id to the child component.

     @Input() selectedItem:number;
      @Output() yesClicked: EventEmitter<any> = new EventEmitter();
     @Output() noClicked: EventEmitter<any> = new EventEmitter();
    

    you can call a method in child component when yes in clicked. in that method you have to emit the created event.

    confirm(){
        this.yesClicked.emit();
    }
    
    hide(){
        this.noClicked.emit();
    }
    

    in child component html you have to call the "confirm" method in childComponent for yes click event and hide method for "No" click event.

      <div bsModal #childModal="bs-modal" class="modal fade" tabindex="-1" 
        role="dialog" [config]="{backdrop: 'static'}" aria-hidden="true">
        <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-body text-center">
                <p>Do you want to confirm?</p>
                <button type="button" class="btn btn-default" 
        (click)="confirm()">Yes</button>
                <button type="button" class="btn btn-primary" 
        (click)="hide()">No</button>
            </div> 
            </div>
         </div>
       </div>
    

    In parent app.component.html call app.component.ts methods from template to the events emit by the child component as follows.

       <table style="width:100%" class="table table-striped" 
          id="billing_history_table">
         <thead class="head">
            <tr>
                <th>Name</th>
                <th></th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let e of employeelist>
                <td>{{e.firstName}}</td>
                <td><a (click)="clickedItem=e.Id;childModal.show()"><span class="glyphicon 
          glyphicon-trash"></span></a></td>
            </tr>
           </tbody>
          </table>
    
      <app-modal-component #childModal [selectedItem]="clickedItem"(yesClicked)="DeleteEmployee($event)" (noClicked)="hide()" >
    
         </app-modal-component>
    

    In the app component.ts declare a variable for clickedItem Id and declare methods to delete and hide the model.

    clickedItem:number;
    

     DeleteEmployee(id: string) {
            this._usermanagementservice.deleteEmployee(id).subscribe(res => {
                this.LoadAllEmployees();
            })
            }