0

I'm trying to open an ionic modal when an openlayers feature is selected.
I have injected ModalController but it is undefined when it's used from the listener.
I'm assuming it's because of context being different, but how can I resolve this ?
Should I use eventEmitters or rx/observables or is it possible to correctly attach the listener ? Here's the code

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { ModalController } from '@ionic/angular';
    import { SelectActionNichoirPage } from '../../pages/modal/select-action-nichoir/select-action-nichoir.page';

    @Component({
    selector: 'app-openlayers-wrapper',
    templateUrl: './openlayers-wrapper.component.html',
    styleUrls: ['./openlayers-wrapper.component.scss'],
    })
    export class OpenlayersWrapperComponent implements OnInit {
    selectClick;

    constructor(public modalController: ModalController) {
    console.log("Construct modal" , this.modalController); // not Undefined
    }

    initMap() {

    this.map = new OlMap({
      target: 'map',
      layers: [this.layer, observationsVectorLayer],
      view: this.view,
    });

    this.selectClick = new Select({
        condition: click
      });
    this.map.addInteraction(this.selectClick);

    console.log("add listen", this.modalController); // not undefined
    this.selectClick.on('select', function(e) {
       console.log(e.target.getFeatures().getLength() +
            ' selected features');
       console.log("modal ctrl in listener", this.modalController); // UNDEFINED
        });
    this.selectClick.on('select', this.presentModal); 
    }

    async presentModal() {
       console.log("modal ctrl in function", this.modalController);  // UNDEFINED
       const modal = await this.modalController.create({             // exception : no method create on undefined
         component: SelectActionNichoirPage
       });
       return await modal.present();
     }
    }

2 Answers2

1

For a quick fix, that can also help you confirm your intuition about the problem, save a reference to your component before declaring the function, something like this,

var self = this;
this.selectClick.on('select', function(e) {
    console.log(e.target.getFeatures().getLength() +
        ' selected features');
    console.log("modal ctrl in listener", self.modalController); // <- self
    self.presentModal(); <- self
});
cabesuon
  • 4,860
  • 2
  • 15
  • 24
0

Your problem occurs because you use this.presentModal and the closure as callbacks.

The problem is solved by adding the bind function after your callback e.g. this.selectClick.on('select'. this.presentModal.bind(this);

More informations about "this" can be found here How does the "this" keyword work?.

This is how your fixed code can be fixed.

 import { Component, OnInit, ViewChild } from '@angular/core';
    import { ModalController } from '@ionic/angular';
    import { SelectActionNichoirPage } from '../../pages/modal/select-action-nichoir/select-action-nichoir.page';

    @Component({
    selector: 'app-openlayers-wrapper',
    templateUrl: './openlayers-wrapper.component.html',
    styleUrls: ['./openlayers-wrapper.component.scss'],
    })
    export class OpenlayersWrapperComponent implements OnInit {
    selectClick;

    constructor(public modalController: ModalController) {
    console.log("Construct modal" , this.modalController); // not Undefined
    }

    initMap() {

    this.map = new OlMap({
      target: 'map',
      layers: [this.layer, observationsVectorLayer],
      view: this.view,
    });

    this.selectClick = new Select({
        condition: click
      });
    this.map.addInteraction(this.selectClick);

    console.log("add listen", this.modalController); // not undefined
    this.selectClick.on('select', function(e) {
       console.log(e.target.getFeatures().getLength() +
            ' selected features');
       console.log("modal ctrl in listener", this.modalController); // UNDEFINED
        }.bind(this));
    this.selectClick.on('select', this.presentModal.bind(this)); 
    }

    async presentModal() {
       console.log("modal ctrl in function", this.modalController);  // UNDEFINED
       const modal = await this.modalController.create({             // exception : no method create on undefined
         component: SelectActionNichoirPage
       });
       return await modal.present();
     }
    }
Dominic
  • 19
  • 1