4

Im trying to import the a typescript leaflet library into my angular 2 application.

This is my map component. Ive installed leaflet.d.ts with tsd install and my application does not complain about /// <reference path="../../typings/leaflet/leaflet.d.ts"/> but when i try to use a L.map which is a exported module in leaflet.d.ts i get the error "ReferenceError: L is not defined". This is the first time i try to import a external typescript library in angular 2 and clearly im doing something wrong.

/// <reference path="../../typings/leaflet/leaflet.d.ts"/>
import { Component } from 'angular2/core';
@Component({
  selector: 'map',
  template: `
        <div id="map"></div>
  `,
})
export class Map{
    constructor(){
          var map = new L.Map('map', {
             zoomControl: false
         });
    }

package.json

{
  "dependencies": {
    "angular2": "^2.0.0-beta.3",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "normalize.css": "^3.0.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "systemjs": "0.19.6",
    "typings": "^0.6.4",
    "zone.js": "^0.5.11"
  },
  "devDependencies": {
    "concurrently": "^1.0.0",
    "gh-pages": "^0.11.0",
    "grunt": "~0.4.5",
    "grunt-contrib-clean": "^1.0.0",
    "grunt-contrib-copy": "^1.0.0",
    "grunt-contrib-cssmin": "^1.0.0",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-sass": "~0.9.0",
    "grunt-contrib-uglify": "~0.5.0",
    "grunt-shell": "^1.2.1",
    "lite-server": "^2.0.1",
    "normalize.css": "^3.0.3",
    "typescript": "^1.7.5"
  },
  "scripts": {
    "publish": "node publish.js",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
  }
}

tsd.json

{
  "version": "v4",
  "repo": "borisyankov/DefinitelyTyped",
  "ref": "master",
  "path": "typings",
  "bundle": "typings/tsd.d.ts",
  "installed": {
    "leaflet/leaflet.d.ts": {
      "commit": "1da639a106527e0c4010b354a1efe52a3059a291"
    }
  }
}

Could anyone tell me what I am doing wrong?

Thanks!

3
  • I believe you also need connect leaflet.js to your page. d.ts files are only used to tell TypeScript about some JS code, d.ts don't import actual code. Commented Apr 2, 2016 at 16:26
  • Okay. I've got the leaflet js files in a folder in my project. Do you know how i could connect my ts file to this folder? Commented Apr 2, 2016 at 16:30
  • You can just use <script> tag, or dependency manager if you are using some. Commented Apr 2, 2016 at 16:32

4 Answers 4

4

You need to include the leaflet JS file:

System.config({
  map: {
    leaflet: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js'
  },
  packages: {'app': {defaultExtension: 'ts'}} 
});
System.import('app/main')
        .then(null, console.error.bind(console));

Then you can import it in your modules this way:

import {Component, OnInit} from 'angular2/core';
import leaflet from 'leaflet';

See this plunkr: http://plnkr.co/edit/aUo2uvlxC5ji32u01jfF?p=preview.

Sign up to request clarification or add additional context in comments.

2 Comments

how can I add this on my angular-cli config file? I've added on system config as you've mentioned, but import leaflet is not finding the module.
Ditto on that. Would like some info on how to do with angular-cli and webpack.
3

I can suggest you a workaround until angular-cli get better support for 3rd party libs. It worked for me :)

First go to the project directory and type

npm install leaflet --save

then open your angular-cli-build.js and add this line

vendorNpmFiles: [
   ..................
   'leaflet/**/*.js',
    ....................
  ]

now open your src/system-config.ts, write

const map:any ={
     ..................
   'leaflet': 'vendor/leaflet/dist',
    ....................

}

and

const packages: any = {
  'leaflet': {
    format: 'cjs'
  }

};

Open your src/index.html, add this

 <script type="text/javascript" src="vendor/leaflet/dist/leaflet.js"></script>

and dont forget to add the css file also

  <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />

Now open your component where you want to use Leaflet

declare let L: any;
@Component({
  moduleId: module.id,
  selector: 'app-map',
  templateUrl: 'map.component.html',
  styleUrls: ['map.component.css']
})
export class MapComponent implements OnInit, AfterViewInit {
 leafletMap: any;
 ngAfterViewInit() {
    this.leafletMap = L.map("map").setView([23.709921, 90.407143], 7);
 }
}

Tada!! your map loaded :D

1 Comment

I guess you wanted to write 'leaflet': 'vendor/leaflet/dist' in the map array, right?
2

I had to make some changes to get Thierry Templier's answer to work using systemjs and Angular 2.4.

I added Leaflet to my system.config.js file just as he states, but in my component I I had to import it this way:

import * as L from 'leaflet';

and then the L class was recognized in my MapComponent

export class MapComponent {
    let map = L.map("map").setView([38, -77], 13);
            L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            }).addTo(map);
    }

Comments

2

Meanwhile, everything you have to do is calling

npm install @types/leaflet@latest --save

and including the source in index.html.

No other imports or declarations needed. Then, the import could look like

import {control, LatLng, layerGroup, LayerGroup, Map} from "leaflet";

Also, map initialization should happen in ngOnInit(), constructor usage is not meant for logic.

4 Comments

Should this be --save-dev?
@chrismarx I dont know, should it? it's not a development tool, but actual application code, so I guess not
Hmm, the types are only useful for development, types go away during transpilation-
using angular CLI, I still need to add declare var L: any; or ng serve prints Cannot find name 'L' - am I missing something?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.