xdev-software / vaadin-maps-leaflet-flow

A Vaadin Flow Java API for Leaflet Maps 🗺️ Component (https://leafletjs.com/)
https://vaadin.com/directory/component/leafletmap-for-vaadin
Apache License 2.0
34 stars 16 forks source link

Extending this Component with plugins but ReferenceError: L is not defined #340

Closed padmalcom closed 8 months ago

padmalcom commented 8 months ago

Hi, I try to integrate leaflet.browser.print into your component. This is the code I wrote so far but it fails with the error "ReferenceError: L is not defined" in the browser. I understand that L as a placeholder for leaflet is not defined yet but I don't know how to define it before I reference it here.

I tried to import leaflet as @JsModule before the leaflet.browser.print but this had no effect.

Hope you can give me a hint on how to proceed here.

@NpmPackage(value = "leaflet.browser.print", version = "2.0.2")
@Tag("leaflet.browser.print")
@JsModule("leaflet.browser.print/dist/leaflet.browser.print.min.js")
public class LBrowserPrint extends LBaseComponent<LBrowserPrint> {

    public LBrowserPrint(
            final LComponentManagementRegistry compReg,
            final LMap map,
            final LBackendOptions backendOptions
            ) {
        super(compReg, "L.browserPrint($0" + compReg.writeOptionsOptionalParameter(backendOptions) + ")");
    }

    public void print() {
        this.componentRegistry().execJs("let browserPrint = " + this.clientComponentJsAccessor() + ";"
                + "browserPrint.print(L.BrowserPrint.Mode.Landscape());");
    }
}
AB-xdev commented 8 months ago

So I don't think you're annotations are working as they are not annotated on a Vaadin component. Maybe try putting them onto a Vaadin view :)

padmalcom commented 8 months ago

Hi Alex, thanks for your fast reply! I tried to add the annotations to my view but L remains undefined.

I also created a custom component and added it to my view but the error remains. Do you have any other ideas? I looked through your component class by class but I could not find anything you did except adding the NpmPackage and the JsModule and leaflet seems to be imported correctly.

@NpmPackage(value = "leaflet.browser.print", version = "2.0.2")
@Tag("leaflet.browser.print")
@JsModule("leaflet.browser.print/dist/leaflet.browser.print.min.js")
public class LBrowserPrintImport extends Div {

    private static final long serialVersionUID = 1L;

    public LBrowserPrintImport() {
        this.setText("PrintDiv");
    }
}
AB-xdev commented 8 months ago

Another idea on the fly: I'm not quite sure what the @Tag is for, you may tray to remove it.

padmalcom commented 8 months ago

I found out that @Tag is required, when my class extends an existing component e.g. Div and when I furthermore call the super() constructor without any arguments.

I additionally found out that the issue with the missing reference is based on a build error, when I run maven install for production, the npm install is triggered and everything works find. Well, except the print itself :)

You can see my last approach I tested below but the print is not triggered (neither print() nor printNow()) so I give up at this point since my knowledge is not sufficient here.

The issue/question can thus be closed, thanks again for your kind help!

@NpmPackage(value = "leaflet.browser.print", version = "2.0.2")
@JsModule("leaflet.browser.print/dist/leaflet.browser.print.min.js")
@Tag("leaflet.browser.print")
public class LBrowserPrintImport extends Div {

    private static final long serialVersionUID = 1L;

    public LBrowserPrintImport(
            final LMap map,
            final LBackendOptions backendOptions
            ) {
        super();
        getElement().executeJs(
                "window.bp = L.browserPrint($0, $1);",
                map.clientComponentJsAccessor(), "{documentTitle: 'Map printed using leaflet.browser.print plugin'}");
    }

    public void print() {
        getElement().executeJs(
                "window.bp.print(L.BrowserPrint.Mode.Landscape());"
        );
    }

    public void printNow(LMap map) {
        getElement().executeJs("L.browserPrint($0, $1).print(L.BrowserPrint.Mode.Landscape());",
                map.clientComponentJsAccessor(), "{documentTitle: 'Map printed using leaflet.browser.print plugin'}");
    }
}