Ahmed Abdelrahman
Ahmed Abdelrahman

Reputation: 821

Import and use untyped leaflet JS plugin with Typescript 2 in Angular 2 project

I'm using LeafletJS library in Angular 2 application. The library itself is working fine since I've included the type definition (leaflet.d.ts) and of course the leaflet node module.

I'm trying to import a plugin for the leaflet library called "leaflet-canvasicon" and there is no available type definition for it and since it's written in ES5 whenever I try to include it, the compiler is satisfied, yet I recieve the following error at the console:

leaflet-src.js:314
Uncaught TypeError: this.callInitHooks is not a function
    at Object.NewClass (http://localhost:2080/main.bundle.js:58716:8)
    at http://localhost:2080/main.bundle.js:77650:180
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:77652:3)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54476:18)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54411:90)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)
    at Object.<anonymous> (http://localhost:2080/main.bundle.js:54600:70)
    at __webpack_require__ (http://localhost:2080/inline.js:53:30)

I thought of many solutions:

But every time I face compiler issues. I think I'm doing it wrong. How can I include the plugin, keep the compiler satisfied and be able to use it as L.CanvasIcon

Here is package.json file:

 "dependencies": {
        "@angular/common": "2.1.2",
        "@angular/compiler": "2.1.2",
        "@angular/compiler-cli": "2.1.2",
        "@angular/core": "2.1.2",
        "@angular/forms": "2.1.2",
        "@angular/http": "2.1.2",
        "@angular/platform-browser": "2.1.2",
        "@angular/platform-browser-dynamic": "2.1.2",
        "@angular/platform-server": "2.1.2",
        "@angular/router": "3.1.2",
        "@types/leaflet": "^1.0.36",
        "core-js": "^2.4.1",
        "leaflet": "^1.0.1",
        "leaflet-canvasicon": "^0.1.6",
        "leafletjs-canvas-overlay": "^1.0.1",
        "rxjs": "5.0.0-rc.1",
        "ts-helpers": "^1.1.2",
        "zone.js": "^0.6.26"
      },
      "devDependencies": {
        "angular-cli": "1.0.0-beta.19-3",
        "ts-node": "1.6.1",
        "tslint": "3.15.1",
        "typescript": "2.0.6",
        "typings": "^1.5.0"
      }
    }

Upvotes: 4

Views: 2246

Answers (2)

Jonas Tomanga
Jonas Tomanga

Reputation: 1108

Import this file after leaflet if you need to use leaflet plugins in typescript.

declare module L {
    // plugins that extend Class i.e L.MyClass
    export let MyClass:any;
    // plugins that uses class factory i.e myClass
    export let myClass:any;

   //plugins that extend Control comes here i.e L.Control.Navbar
   export namespace Control {
      export let Navbar: any;
   }
   // plugins that have control factories come here i.e. L.control.navbar
  export namespace control {
     export let navbar: any;
  }

  //plugins that extend Layer comes here i.e L.Layer.NewLayer
   export namespace Layer {
      export let NewLayer: any;
   }
  // plugins that have layer factories come here i.e. L.layer.newLayer
  export namespace layer {
     export let newLayer: any;
  }
  //plugins that extend Handler comes here i.e. L.Handler.NewHandler
   export namespace Handler {
      export let NewHandler: any;
   }
  // plugins that have handler factories come here i.e. L.Handler.newHandler
  export namespace handler {
     export let newHandler: any;
  }
}

You can be explicit with the types if you want to.

Upvotes: 1

rzelek
rzelek

Reputation: 4023

This is runtime error not related to missing typings. The problem is related to leaflet version mismatch.

It seems that leaflet-canvasicon is designed for older versions of leaflet. Try to fallback to leaflet with version 0.7.x.

 "dependencies": {
        "@angular/common": "2.1.2",
        "@angular/compiler": "2.1.2",
        "@angular/compiler-cli": "2.1.2",
        "@angular/core": "2.1.2",
        "@angular/forms": "2.1.2",
        "@angular/http": "2.1.2",
        "@angular/platform-browser": "2.1.2",
        "@angular/platform-browser-dynamic": "2.1.2",
        "@angular/platform-server": "2.1.2",
        "@angular/router": "3.1.2",
        "@types/leaflet": "0.7.x",
        "core-js": "^2.4.1",
        "leaflet": "0.7.x", // note the change
        "leaflet-canvasicon": "^0.1.6",
        "leafletjs-canvas-overlay": "^1.0.1",
        "rxjs": "5.0.0-rc.1",
        "ts-helpers": "^1.1.2",
        "zone.js": "^0.6.26"
      },
      "devDependencies": {
        "angular-cli": "1.0.0-beta.19-3",
        "ts-node": "1.6.1",
        "tslint": "3.15.1",
        "typescript": "2.0.6",
        "typings": "^1.5.0"
      }
    }

For the future, you can remember that this.callInitHooks is not a function is typical problem after loading old extensions to leaflet version >=1

Upvotes: 2

Related Questions