33

I am using ng-bootstrap with Angular 4, specific use case is the modal with "Component as content" (second scenario from https://ng-bootstrap.github.io/#/components/modal/examples).

I would like to emit some data from the child to the parent. For this I have created a non-working plunk from the example:

modal.component.ts

import {Component, Input, Output, EventEmitter} from '@angular/core';    
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-content',
  template: `
    <div class="modal-header">
      <h4 class="modal-title">Hi there!</h4>
    </div>
    <div class="modal-body">
      <p>Hello!</p>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-secondary" (click)="testclick('teststring')">Testclick</button>
    </div>
  `
})
export class NgbdModalContent {
  @Output() clickevent = new EventEmitter<string>();

  constructor(public activeModal: NgbActiveModal) {}
  
  testclick(teststring: string) {
    this.clickevent.emit(teststring);
  }
}

@Component({
  selector: 'ngbd-modal-component',
  templateUrl: 'src/modal-component.html'
})
export class NgbdModalComponent {
  constructor(private modalService: NgbModal) {}

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
  }
}

modal.component.html

<button class="btn btn-lg btn-outline-primary" (click)="open()">Launch demo modal</button>

As you can see, I have only added the EventEmitter into the NgbdModalContent Component. What I would like is the NgbdModalComponent to receive the testclick event and log it to the console. Where can I put it in the code above?

I am aware there is a very similar question here Event emitter from bootstrap modal to parent but I think it is still a very different implementation scenario since I am opening the modal directly as component here.

Obviously I would prefer some simple solutions where I do not have to go into the code for modalService itself...

IAfanasov
  • 4,775
  • 3
  • 27
  • 42
Ruehri
  • 828
  • 2
  • 11
  • 21

1 Answers1

67

It is actually very simple as you can directly subscribe to the @Output events of the component opened as modal's content:

export class NgbdModalComponent {
  constructor(private modalService: NgbModal) {}

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
    modalRef.componentInstance.clickevent.subscribe(($e) => {
      console.log($e);
    })
  }
}

Here is a working plunker: http://plnkr.co/edit/rMJ7qfSSLK0oHspIJbDB?p=preview

Side note: I'm not sure what is your exact use case but the answer to Event emitter from bootstrap modal to parent shows preferred method of communication between modal opener and a component used as a modal's content.

IAfanasov
  • 4,775
  • 3
  • 27
  • 42
pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • That worked well! As a ng2 learner I wasn't aware that you could simply subscribe to the componentInstance. The docs and tutorials typically teach you to add event binding in the template (e.g., (clickevent)="function" in a html tag). Since there was no tag in the template to add the event binding (only the open() function), I wasn't sure where to add it. This helped a lot. – Ruehri Jul 25 '17 at 19:12
  • 5
    Thank you. For angular2 with ngx-bootstrap, i just had to use "content" in place of "componentInstance". – Ali Faizan Oct 12 '17 at 12:12
  • `modalRef.componentInstance` not available in angular 7, it is giving error to me – Veshraj Joshi Dec 24 '18 at 11:05
  • 1
    @Veshraj Joshi you can use `modelRef.content` instead of `modalRef.componentInstance` as @Ali Faizan said. – Asad Shakeel Jan 09 '19 at 06:39
  • @AsadShakeel I wrote answer in https://stackoverflow.com/questions/42681556/event-emitter-from-bootstrap-modal-to-parent/53912926#53912926, thanks for your comment. Please check whether it is correct or not. – Veshraj Joshi Jan 09 '19 at 07:10