0

I am using ng-bootstrap with Angular in typescript. The Particular Example I have incorporated from the Documentation is Components as content.

From the parent class I pass on a list of all the keys available from a specific JSON that is of my interest. If the event for the modal is triggered, the User sees all the values from the list within the modal and can delete the values according to preference.

enter image description here

Modal Content Class

Component

@Component({
    selector: 'ngbd-modal-content',
    template: `
    <div class="modal-header">
      <h4 class="modal-title">Edit your Semantic Query</h4>
      <button type="button" 
       class="close" aria-label="Close" 
       (click)="activeModal.dismiss('Cross click')"> <!--Cross Button on Top-->
        <span aria-hidden="true">&times;</span>
      </button>
    </div>

    <div class="modal-body">
        Available Keywords that can be Removed:
      <ul *ngIf="modalKeys.length > 1"> <!--Display More than 1 Keywords -->

          <li *ngFor="let eachKey of modalKeys; let i=index;">
              <div>
                <span><code>{{eachKey}}</code></span>
                 <!-- Provide Red cross Button to remove the keyword-->
                 <button class="btn-xs btn-danger" *ngIf="i > 0" 
                   (click)="removeQParam(eachKey, i);">&times;</button>
              </div>
          </li>
      </ul>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-dark" 
        (click)="activeModal.close('Close click')">Close</button>
    </div>
  `
})

Class

export class NgbdModalContent {
    @Input() modalKeys: string[] = [];
    @Output() removedKeys = new EventEmitter();
    constructor(public activeModal: NgbActiveModal) {}

    removeQParam(keyword: string, clickedIndex: number) {
        // remove the keyword from the Modal's list
        this.modalKeys.splice(clickedIndex, 1);
        // send the removed keyword back to the parent
        this.removedKeys.emit(keyword);
    }

}

I Call the modal (from Parent) on a <code (click)=callEditModal()></code>

where the callEditModal() is as follows:

let keys: string[] = []; // empty array for all keys of Object semQJSon

        for (let key in this.semQJSon) {
            if (this.semQJSon.hasOwnProperty(key)) {
                keys.push(key); // push all available keys of the object
            }
        }
         // taken from the ng-bootstrap docs
        const modalRef = this.modal.open(NgbdModalContent);
         // pass all the keys to the @Input() modalKeys in ModalContent Class
        modalRef.componentInstance.modalKeys = keys;

Question

How do I catch this Emitted Event Value in the Parent?

I tried using <ng-template (removedKeys)=processModalInteraction($events) in my Parent Component's HTML but I get the following error:

Event binding removedKeys not emitted by any directive
 on an embedded template. Make sure that the event name is spelled correctly 
and all directives are listed in the "@NgModule.declarations". ("
     <ng-template [ERROR ->](removedKeys)="processModalInteraction($event)"</ng-template>

If I use the <ngbd-modal-content></ngbd-modal-content> within the Parent's HTML Code I can see the modal which is not what I want

Shan-Desai
  • 3,101
  • 3
  • 46
  • 89

1 Answers1

0

I found a related StackOverflow Query which provided a solution.

Instead of using EventEmitter, closing the activeModal by passing the keyword does the trick.

Class

export class NgbdModalContent {
    @Input() modalKeys: string[] = [];
    constructor(public activeModal: NgbActiveModal) {}

      removeQParam(keyword: string, clickedIndex: number) {
        // remove the keyword from the Modal's list
        this.modalKeys.splice(clickedIndex, 1);
        // send the removed keyword back to the parent
        this.activeModal.close(keyword);
      }

}

Parent Class

const modalRef = this.modal.open(NgbdModalContent);
        modalRef.componentInstance.modalKeys = keys;
        modalRef.result
            .then((result) => {
                console.log(result); // this is where you can capture your modal activity
            });
Additional Info

Not only strings but Objects can be sent back to the parent too. For Instance,

this.activeModal.close({'result': keyword})

would provide the JSON at the Parent's console.log

Shan-Desai
  • 3,101
  • 3
  • 46
  • 89