Access native Ionic function within jQuery


#1

Hi,

I am using Wayfinding (https://github.com/ucdavis/wayfinding) in my mobile app and would like to trigger an Ionic modal when the user clicks on one of the rooms. At the moment, there is a simple alert:

$('#Rooms a', el).click(function (event) {
				
event.preventDefault();
				
alert('You have clicked on room ' + $(this).prop('id'));

});

However I would like to use this.presentModal() which references a simple function outside the jQuery code:

presentModal() {
let modal = this.modalCtrl.create(ModalPage);
modal.present();
}
$('#Rooms a', el).click(function (event) {
				
event.preventDefault();
				
this.presentModal();

});

In this case, “this” isn’t the right way to access the presentModal() function. Does anyone know what is?

Thanks!


#2

Just replace
function (event)

With
(event) =>

And it’ll properly retain this.


#3

Thanks for the quick reply. Unfortunately, no joy. With this code, nothing happens if I click a room.

$('#Rooms a', el).click((event) => {
				
event.preventDefault();
this.presentModal();

});

I wonder if it is because the click event itself is inside a function and that function in turn is inside the initial declaration for Wayfinding. I have eliminated all of the other functions, but this is where everything sits in relation to each other.

presentModal() {
  let modal = this.modalCtrl.create(ModalPage);
  modal.present();
}

$.fn.wayfinding = function (action, options) {
  function cleanupSVG(target, el) {
    $('#Rooms a', el).click((event) => {
				
      event.preventDefault();
      this.presentModal();

    });
  }
}

Thanks.


#4

Yeah that’d probably be it.

In an Ionic app you pretty much never want to type function, the reason being that as you’ve found out it doesn’t properly retain this.

So whenever you’d type function, use the fat arrow syntax () => instead.

So update the wayfinding line to:
$.fn.wayfinding = (action, options) => {

Edit:
Oh, then there’s cleanSVG. Not sure about that line off the top of my head. Just woke up, so I’ll get some coffee. I’m not sure if the aforementioned syntax will work in that case.


#5

I just tested the change to $.fn.wayfinding = function (action, options) { and it has other effects further on in the rest of the jQuery code, notably an instance of this.each(function () { which is then not recognised.

Is there any way to reach presentModal() without “this”?

If it helps, I can upload the entire file.

Edit:
If I use $('#Rooms a', el).click((event) => {, I lose the correct “this” behaviour in order to retrieve the ID from the clicked room using $(this).prop('id').


#6

I think when you want to use jQuery with typescript you need some definition file that tell typescript how to use jquery.

I cant open the link from here but I think you will find more Infos here


#7

@Jacktoolsnet This isn’t an issue with typings, but an issue with retaining the proper context.

I’ve forgotten how much jQuery also utilizes this. In this case I’d do some manual context capturing.

let self = this;
$.fn.wayfinding = function (action, options) {
  function cleanupSVG(target, el) {
    $('#Rooms a', el).click(function (event) {
				
      event.preventDefault();
      self.presentModal();

    });
  }
}

This is assuming that this block of code is executed from an Ionic context.


#8

Spectacular, thanks! It works perfectly.


#9

Hi,

I hesitate to start a new topic because I have a quick question about accessing jQuery functions.

The very latest version of Wayfinding includes a pan/zoom feature which uses the jquery.panzoom dependency. I first installed this dependency successfully using npm install jquery.panzoom and then I added import * as panzoom from 'jquery.panzoom'; under import * as $ from 'jquery';

However during the build, I get the message ‘panzoom’ is declared but never used.

It is certainly used in a little function within Wayfinding:

function initializePanZoom(el) {
  el.panzoom({
    minScale: 1.0,
    contain: 'invert',
    cursor: 'pointer'
  });
}

And it is called in one of the main functions:

initializePanZoom($(svgDiv));

I was wondering if the .panzoom function requires a special declaration?

There are no further errors at buildtime but the map no longer appears in the application. I suspect that .panzoom is responsible.

Thanks :slight_smile:


#10

That sounds about right. It should just be a warning.

With the way jQuery/Panzoom works I’m not sure that there’s a way to get rid of it, unless your code works with removing the Panzoom import. It may not be required, as I don’t believe jQuery has treeshaking anyway.


#11

Hi,

I made all of the updates to Wayfinding but excluded all references to .panzoom; the map loaded just fine so the problem is certainly there. When I used Safari console to inspect what was happening when .panzoom was included, it confirmed that .panzoom was undefined, suggesting that it was not a loaded resource.

24

I can only conclude that I’m not loading panzoom correctly using import * as panzoom from 'jquery.panzoom'; I reinstalled the node module just in case but there was no change. I also tried import panzoom from 'jquery.panzoom'; but nothing.

19

Do you think there is another way I can load in this function? Maybe using the original js file available at the Github (https://github.com/timmywil/jquery.panzoom)?

Edit: I also tried import { panzoom } from 'jquery.panzoom'; as well as creating a declarations.d.ts file with the declaration inside: declare module 'jquery.panzoom'; neither of these seem to work. In addition, I noticed that in the node module jquery.panzoom, the function uses a capital P, so Panzoom. I wonder if that could have an impact!