17

That's the way I use the ng2-bootstrap modal:

import {Component} from '@angular/core';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'add-customer-modal',
  template: `
    <template #test let-c="close" let-d="dismiss">
      <div class="modal-header">
        <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" (click)="c('Close click')">Close</button>
      </div>
    </template>
    <button type="button" class="btn btn-primary btn-sm" (click)="open(test)"><i class="fa fa-plus"></i> <i class="fa fa-user-o"></i></button>
  `
})
export class AddCustomerModal {

  constructor(private modalService: NgbModal) {}

  open(content) {
    this.modalService.open(content, { size: 'lg' }).result.then((result) => {
      console.log(result);
    }, (reason) => {
      console.log(reason);
    });
  }
}

I'am a little bit confused, because I thought the content is used to pass parameters to the modal. But in my opinion it's only the name the open method needs to find the correct template?

So how can I pass parameters?

Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
robert
  • 797
  • 3
  • 9
  • 23
  • 1
    read here for more info: [http://stackoverflow.com/questions/39464345/best-practice-for-calling-the-ngbmodal-open-method](http://stackoverflow.com/questions/39464345/best-practice-for-calling-the-ngbmodal-open-method) – Poul Kruijt Dec 14 '16 at 10:13
  • @PierreDuc Thanks! And how can I pass parameters/data to the modal? – robert Dec 14 '16 at 10:29
  • For all these people trying to find a way to make this work "the easy way," it isn't magic. If you are using the (lazy) "pass by TemplateRef" method, you CAN NOT use componentInstance since it is undefined when a TemplateRef is passed into the NgbModal. – Elysiumplain Mar 22 '19 at 17:50

5 Answers5

19

Anyone still stumbling onto this might find this handy, all you need to do is declare a field inside your ModalComponent like this:

 modalHeader: string;
 advertiser: Advertiser;

You can set these fields by doing the following when you are opening a modal.

advertiserModalShow() {
    const activeModal = this.modalService.open(AdvertiserModal, { size: 'lg' });
    activeModal.componentInstance.modalHeader = 'Advertiser';
    activeModal.componentInstance.advertiser = this.selectedAdvertiser;
}

In your template you can access them like this:

value={{advertiser.code}}

Hope this helps.

Kanso Code
  • 7,479
  • 5
  • 34
  • 49
Sadiq Ali
  • 1,272
  • 2
  • 15
  • 22
14

To pass parameters/data to the modal, my guess would be to use the componentInstance:

open(content) {
    const modal: NgbModalRef = this.modalService.open(content, { size: 'lg' });

    (<MyComponent>model.componentInstance).data = 'hi';

    modal.result.then((result) => {
      console.log(result);
    }, (reason) => {
      console.log(reason);
    });
}

This assumes that the componentInstance is of type MyComponent and that it has a public property data

Poul Kruijt
  • 69,713
  • 12
  • 145
  • 149
  • I get this error. Property 'componentInstance' does not exist on type 'BsModalRef'. – Riyas Kp May 16 '18 at 07:49
  • 1
    @RiyasKp That's because you are using `ngx-bootstrap` and not `ng-bootstrap`. I believe you have to use `content` instead of `componentInstance` – Poul Kruijt May 16 '18 at 08:07
6

There is a better approach to handle data in the modal if you need to have data immediately after modal construction. Using angular injector technic.

  1. Define a model for your data.
class CustomModalOptions {
  stringProp: string; 
  numberProp: number;
}
  1. Build your modal somewhere in your component:
this.modal.open(MyModal, {
  injector: Injector.create([{
    provide: CustomModalOptions, useValue: { stringProp: "foo bar", numberProp: 17 }
  }], this.injector)
});
  1. Handle data retrieve in your Modal Component
@Component({ ... })
class MyModal {
  constructor(private options: CustomModalOptions) {
    console.log(this.options.stringProp);
    console.log(this.options.numberProp);
  }
}
Kanso Code
  • 7,479
  • 5
  • 34
  • 49
  • Can you explain how to define `this.injector` ? And can I merely use a literally string for `provide` and how to pass it to the open component. Thx. – SHUMING LU Jun 02 '21 at 06:15
  • Everywhere is the same... IF modal matches the component. But what if it does not? How to pass arguments to modal, if it corresponds to TemplateRef? – Alexander Apr 29 '23 at 00:01
2

Here's how you can pass data to your HTML Template in Angular2

import {Component} from '@angular/core';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'add-customer-modal',
template: `
<template #test let-c="close" let-d="dismiss">
  <div class="modal-header">
    <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
      <span aria-hidden="true">&times;</span>
    </button>
    <h4 class="modal-title">Modal title</h4>
  </div>
  <div class="modal-body">
     {{MESSAGE_DATA}}
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-secondary" (click)="c('Close click')">Close</button>
  </div>
</template>
<button type="button" class="btn btn-primary btn-sm" (click)="open(test)"><i class="fa fa-plus"></i> <i class="fa fa-user-o"></i></button>`})

export class AddCustomerModal {
   MESSAGE_DATA : any;
   constructor(private modalService: NgbModal) {}

   open(content) {
      this.MESSAGE_DATA = "PASS DATA TO ANGULAR2 MODAL"
      this.modalService.open(content, { size: 'lg' }).result.then((result) => {
         console.log(result);
      }, (reason) => {
      console.log(reason);
    });
 }
}

check how MESSAGE_DATA is used inside HTML Template.

Devesh Jadon
  • 7,004
  • 4
  • 22
  • 27
  • 2
    you define MESSAGE_DATA in parent component and use it there, that's easy. How about define MESSAGE_DATA in open() and pass it to HTML? – Peter Huang Apr 19 '18 at 21:45
1

I would suggest you look at the Child Modal example here ng2-bootstrap documentation for modals. Just add public variables to the parent component and use them in your modal using standard binding techniques.

So in the example add this to the template like so:

      <div class="modal-body">
          {{parentMessage}}
      </div>

and change the component like this:

export class DemoModalChildComponent {
  @ViewChild('childModal') public childModal:ModalDirective;
  parentMessage = 'I am a child modal, opened from parent component!'; //Add this

Now you that you are passing in data from the parent component you can pass data to the parent component by following the standard patterns.

GlennSills
  • 3,977
  • 26
  • 28