0

I'm trying to dismiss my modal in ionic 2.

I have component which looks like this:

export class DynamicModalComponent<T extends IHasId> {

    modalOptions: DynamicModalOptions<T>

    constructor(public navCtrl: NavController, public navParams: NavParams) {
        this.modalOptions = navParams.get('modalOptions');
    }

    close() {
        this.modalOptions.viewCtrl.dismiss();
    }
}

and my html looks like this:

<ion-header>
  <ion-navbar align-title="center">
    <ion-title> Dynamic Modal Header </ion-title>
    <ion-buttons end>
      <button (click)="close()" ion-button>
        <ion-icon name="save"></ion-icon>
        &nbsp;Cancel
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

When I click the cancel button, my function gets triggered but nothing dismisses. I don't think the issue would be in the calling class but just incase ill post the relevant pieces:

constructor(public navCtrl: NavController, public viewCtrl: ViewController, public navParams: NavParams, public baseProvider: UserSkills,
    public enumProvider: Enums, public modalCtrl: ModalController, routes: Routes) {
}

showModal(modalOptions: DynamicModalOptions<UserSkill>) {
    let modal = this.modalCtrl.create(DynamicModalComponent, { modalOptions });
    modal.present();
    return modal;
}

onItemClick(entity) {
    var modalOptions = this.getDynamicModalOptions(entity);
    this.showModal(modalOptions);
}

getDynamicModalOptions(entity: UserSkill): DynamicModalOptions<UserSkill> {
    var modalOptions = new DynamicModalOptions<UserSkill>();

    modalOptions.entity = entity;
    modalOptions.editOptions = this.editOptions;
    modalOptions.inputMetadata = this.getInputMetadata(); 
    modalOptions.viewCtrl = this.viewCtrl;

    return modalOptions;
}
4
  • Does getDynamicModalOptions get called this way? I'm not sure of the need to couple ViewController since you can always inject it in the constructor for DynamicModalComponent Commented Jul 30, 2017 at 22:34
  • Really, I gotta investigate because ViewController and NavController are special they can't be inject into providers easily, this code was originally done thorough a provider but I extracted it into a component
    – johnny 5
    Commented Jul 30, 2017 at 22:49
  • 1
    @OluwafemiSule that fixed it, if you post it as an answer I'll mark it correct!
    – johnny 5
    Commented Jul 30, 2017 at 23:18
  • 1
    Yes, the problem was that you were passing the wrong instance of the ViewController. You were passing the instance of the ViewController of the caller, and not the ViewController that represents the modal. Therefore the viewCtrl.dismiss();didn't do anything (since the modal exists in the DynamicModalComponent and not the caller component). Another way to fix this kind of issues, is to use the injector (public injector: Injector) to get the right instance (viewCtrl = this.injector.get(ViewController);) on the DynamicModalComponent component Commented Jul 31, 2017 at 4:23

1 Answer 1

1

As noted by @sebaferras, the wrong instance of ViewController is being passed here.

You can ask the injector to get the right instance of ViewController by injecting the Injector in the constructor of DynamicModalComponent. This way ViewController can be resolved in ngOnInit.

constructor(public navCtrl: NavController, 
            public navParams: NavParams, 
            private injector: Injector) {
  this.modalOptions = navParams.get('modalOptions');
}

ngOnInit() {
  this.viewCtrl = this.injector.get(ViewController);
}

close() {
  this.viewCtrl.dismiss();
}

A better technique is to inject ViewController in the constructor of DynamicModalComponent and have Angular take care of things for you.

constructor(public navCtrl: NavController, 
            public navParams: NavParams, 
            private viewCtrl ViewController) {
  this.modalOptions = navParams.get('modalOptions');
}

close() {
  this.viewCtrl.dismiss();
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.