leaflet-easyPrint icon indicating copy to clipboard operation
leaflet-easyPrint copied to clipboard

Use leaflet-easyPrint in Typescript app

Open ialixandroae opened this issue 5 years ago • 17 comments

I tried to import the plugin into a Typescript app and also added the code into the typings file to extend L.control from leaflet but got Uncaught TypeError: L.control.easyPrint is not a function error.

This is the code from typings file:

import 'leaflet';

declare module 'leaflet' {
    
    namespace Map {
        export interface MapOptions {
            
            easyPrintControl? : boolean;
        }
    }

    export interface ControlStatic {
        
        EasyPrint: Control.EasyPrintStatic;
    }

    namespace Control {

     
        export interface EasyPrintStatic {
            new (options?: IEasyPrintConstructorOptions): EasyPrint;
            
        }

 
        
        export interface IEasyPrintConstructorOptions {
            title: string;
            position: string;
    
        }

        export interface EasyPrint extends L.Control {
            
        }
        
    }

    export namespace control {
            export function easyPrint (options?: Control.IEasyPrintConstructorOptions): Control.EasyPrint;
    }
}

For some reason, my IDE interpretor accepts easyPrint function on L.control but my browser throws the error...

Not really sure where to go from here to be able to use the plugin

ialixandroae avatar Mar 19 '19 15:03 ialixandroae

Hmmm I dont know much about typescript sorry @ialixandroae :(

rowanwins avatar Mar 19 '19 22:03 rowanwins

@rowanwins thanks for your reply! Oh, I'm sorry to hear that :(

I'll try to have this done; also maybe somebody else interested could help

ialixandroae avatar Mar 20 '19 10:03 ialixandroae

Hi, I think you can use easyPrint like this : First install easyPrint with npm npm install leaflet-easyprint --save

Then, use it in your typescript file.

import * as Leaflet from 'leaflet';
import 'leaflet-easyprint';
...
map : Leaflet.Map;
...
drawMap() {
        //initialize the map
        this.map = Leaflet.map('map',
            {
                center: [...],
                zoomDelta: 1,
                zoom: 14
            });       
        (Leaflet as any).easyPrint({
            title: 'My awesome print button',
            position: 'bottomleft',
            sizeModes: ['A4Portrait', 'A4Landscape']
        }).addTo(this.map);
}
...

@ialixandroae

And you should see the easyPrint control the the map

martinhouryfors avatar Mar 26 '19 15:03 martinhouryfors

Thanks for sharing @martinhouryfors

rowanwins avatar Mar 27 '19 07:03 rowanwins

@martinhouryfors thanks for your message and feedback! Unfortunately I get the same error L.easyPrint is not a function

I imported leaflet-easyprint in my main .ts file (where the map object is created) using import 'leaflet-easyprint';

After the map object is created, I used :

(L as any).easyPrint({
            title: 'My awesome print button',
            position: 'bottomleft',
            sizeModes: ['A4Portrait', 'A4Landscape']
}).addTo(map); 

Maybe the code is ok but something in the typings file is wrong...

ialixandroae avatar Mar 27 '19 10:03 ialixandroae

Hello ialixandroae,

Did you find a solution for this problem?

jlaverdure-talis avatar Dec 10 '19 09:12 jlaverdure-talis

Hi @jlaverdure-talis ,

Unfortunatelly no and I haven't tried since. At the moment I'm not sure if this is something in the core of the library or something with my Typescript configuration (something wrong or missing?)

ialixandroae avatar Dec 10 '19 09:12 ialixandroae

I'm also facing the same issue. Trying to use it in a React web app. Did anyone manage to find the solution?

sushiljain1989 avatar Mar 05 '20 12:03 sushiljain1989

You will want to create a declaration module leaflet-easyprint.d.ts and use the module augmentation functionality of Typescript.

import { Control } from 'leaflet';

export class EasyPrintControl extends Control {
  // control specific methods and properties here
}

export interface EasyPrintOptions {
    hidden: boolean;
    exportOnly: boolean;
    // ...
}

declare module 'leaflet' {
  export function easyPrint(options: EasyPrintOptions): EasyPrintControl;
}

Then where used you import

import * as L from 'leaflet';
import { Map } from 'leaflet';
import 'leaflet-easyprint';
import { EasyPrintControl, EasyPrintOptions } from 'pathTo/leaflet-easyprint'; //the declaration file.

I really wish a new major release of leaflet would come along the is either written in TS or at least more closely aligns with Ecmascript classes. Seeing every object as type "NewClass" makes type checking difficult at runtime. The augumentation method of creating classes essentially ignores encapsulation principles.

Anyway, hope that helps.

rcollette avatar Mar 30 '20 20:03 rcollette

Hi @rcollette , Thanks for your feedback and message! I've tried your proposal and I don't have any problems at compilation time but at runtime.

I am getting Uncaught TypeError: L.easyPrint is not a function in the browser console.

This comes when I run:

L.easyPrint({
            title: 'Test',
            position: 'bottomright',
            sizeModes: ['A4Portrait', 'A4Landscape']
        }).addTo(map);

ialixandroae avatar Apr 01 '20 17:04 ialixandroae

Just double checking, do you have the leaflet imports before the easyprint imports. Sometimes an ide will reorder the imports.

I can't wait till we move away from global imports like this.

rcollette avatar Apr 02 '20 12:04 rcollette

Hello @rcollette , can you please share how you used those controls after creating declaration file and importing from it? I am using this library inside a Vue + TS project and I cannot figure out how to actually trigger printing map on a function call.

yog3sha avatar Oct 26 '20 06:10 yog3sha

@yog3sha - I forget the reason but we had some issue with easyprint and had to remove it from the project. We wound up posting the current map image to to the server to generate PDFs server side.

rcollette avatar Oct 29 '20 17:10 rcollette

@rcollette - Could you elaborate on how you achieved this? It is almost exactly our requirement. Actually need the the file to be downloaded to the server. Looking at WGET or CURL, but I need this to be automatic and not button fired.

john-chase-noaa avatar Mar 29 '21 18:03 john-chase-noaa

@john-chase-noaa I can post the methodology, but not specific code.

Use domToImage to convert the mapPane to a dataUrl Make an API call to a Node server that includes the dataUrl Use PdfKit.PdfDocument.image() to render the data url in the pdf document.

You will likely not get a 100% accurate rendering of all layers that are on the screen because not everything is in the mapPane. I want to say that the attributions and controls aren't part of the generated image. So we passed the attributions to the server as well and rendered them elsewhere in our PDF Document.

rcollette avatar Mar 29 '21 19:03 rcollette

@rcollette - Thanks much, that's great info, code not necessary...

john-chase-noaa avatar Mar 29 '21 19:03 john-chase-noaa

Je ne sais pas s'ils ont corrigé le bug mais (L as any).easyPrint fonctionne pour moi mais il ne peut pas inmprimer les icones. Qlq sais pourquoi?

GhadaAjimiDblog avatar Jul 28 '22 13:07 GhadaAjimiDblog