Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 ng-bootstrap Modal: How to pass data to entry component

I'm trying to send data to a custom modal content component so I can call it from any other component and not repeat code. I'm new to Angular 2 and have followed the "Components as content" demo of ng-boostrap as well as the "Component Interaction" in the Angular docs and have not found a way to get this to work or an example for this case.

I can get the modal to open, but not with dynamic content. I've tried the @Input and the variable approach with no success. I've also added ModalService to the providers in app.module.ts. This is what I have with both approaches that doesn't work:

page.component.html:

<a (click)="modal('message')">
<template ngbModalContainer><my-modal [data]="data"></my-modal></template>

page.component.ts:

import { Component } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ModalService } from '../helpers/modal.service'
import { ModalComponent } from '../helpers/modal.component'

@Component({
  selector: 'app-page',
  templateUrl: './page.component.html',
  styleUrls: ['./page.component.scss'],
  entryComponents: [ ModalComponent ]
})

export class PageComponent {
  data = 'customData'
  constructor (
    private ngbModalService: NgbModal,
    private modalService: ModalService
   ) { }

  closeResult: string
  modal(content) {
    this.data = 'changedData'
    this.modalService.newModal(content)
    this.ngbModalService.open(ModalComponent).result.then((result) => {
      this.closeResult = `Closed with: ${result}`
    }, (reason) => {
      this.closeResult = `Dismissed ${reason}`
    });
  }
}

modal.service.ts:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';

@Injectable()
export class ModalService {
  private modalSource = new Subject<string>()
  modal$ = this.modalSource.asObservable()
  newModal(content: string) {
    this.modalSource.next(content)
  }
}

modal.component.ts:

import { Component, Input, OnDestroy } from '@angular/core';
import { Subscription }   from 'rxjs/Subscription';
import { ModalService } from './modal.service'

@Component({
  selector: 'my-modal',
  template: `
    <div class="modal-body">
    {{data}}
    {{content}}
    </div>
  `
})

export class ModalComponent implements OnDestroy {
  @Input() data: string
  content = 'hello'

  subscription: Subscription
  constructor(
    private modalService: ModalService
  ) {
    this.subscription = modalService.modal$.subscribe(
      content => {
        this.content = content
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Using angular v2.1.0, angular-cli v1.0.0-beta.16, ng-bootstrap v1.0.0-alpha.8

like image 491
asabido Avatar asked Oct 14 '16 16:10

asabido


People also ask

How do I pass data to modal popup?

When the submit button is clicked, it invokes the jQuery function. The data entered the text area is extracted using the val() method into the text variable. This text string is passed to the modal body using the html() method of jQuery.

How can I get dynamic data from bootstrap modal?

Load Dynamic Content from Database in Bootstrap ModalBy clicking the Open Modal ( . openBtn ) button, the dynamic content is loaded from another PHP file ( getContent. php ) based on the ID and shows on the modal popup ( #myModal ).


2 Answers

I solved it! Here's how to do it:

  • In the component(from where you are opening the modal) do this:

    const modalRef = this.modalService.open(ModalComponent);
    
    modalRef.componentInstance.passedData= this.dataToPass;
    
    modalRef.result.then(result => {
      //do something with result
    }                                                       
    
  • In the modal component(receiving end):

    export class ModalComponent { 
    
     passedData: typeOfData;     // declare it!
    
     someFunction() {     // or some  lifecycle hook 
      console.log(this.passedData)  // and then, use it!
     }
    
    // rest of the ModalComponent 
    }
    
like image 65
BlackBeard Avatar answered Oct 28 '22 21:10

BlackBeard


Just provide a service and inject it to VideoModalComponent and PageComponent then you can use this service to communicate.

See https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service for more details and examples.

like image 3
Günter Zöchbauer Avatar answered Oct 28 '22 21:10

Günter Zöchbauer