0
votes

I am facing this issue with openUI5 and Leafletjs using a custom control from library.

Error:

"The renderer for class demo.map.SimpleMap is not defined or does not define a render function! Rendering of __map0 will be skipped!"...

library.js

sap.ui.define([
'jquery.sap.global',
'sap/ui/core/library'],
function(jQuery){
                "use strict";
                sap.ui.getCore().initLibrary({
                        name: 'demo.map',
                        version: '1.0.0',
                        dependencies: ['sap.ui.core'],
                        types: [],
                        interfaces: [],
                        controls:[
                                'demo.map.SimpleMap'
                        ],
                        elements:[]
                });
                return demo.map;
        });

SimpleMap.js

sap.ui.define([
'jquery.sap.global',
'sap/ui/core/Control', 
'./library'], function(jQuery, Control, library){
                    "use strict";

                    let SimpleMap = Control.extend('demo.map.SimpleMap',{
                            metadata:{
                                    library: 'demo.map',
                                    properties:{}
                            }
                    });

                    SimpleMap.prototype.drawMap = function(){
                            this.controlAspect = parseInt(450) / parseInt(350);
                            let map = L.map('map').setView([39.7166700,-8],8);
                            L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
                    }

                    SimpleMap.prototype.onAfterRendering = function(){
                            this.drawMap();
                    }

                    return SimpleMap;
            }, true);

SimpleMapRenderer.js

sap.ui.define(['jquery.sap.global'], function(jQuery){
            "use strict";

            let SimpleMapRenderer = {};

            SimpleMapRenderer.renderer = function(oRm, oControl){
                    oRm.write('<div ');
                    oRm.writeControlData(oControl);
                    oRm.write('>');
                    oRm.write('</div>');
            }

            return SimpleMapRenderer;
    });

Startpage.view.xml

<mvc:View controllerName="sap.ui.demo.fiori.controllers.Startpage" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:layout="sap.ui.layout">
    <Page title="Fiori Tile Demo">
            <layout:VerticalLayout class="sapUiResponsiveMargin">
                    <Title titleStyle="H2" text="Launchpad Menu" class="sapUiTinyMarginBegin"/>
                    <layout:HorizontalLayout allowWrapping="true" id="layout">

                    </layout:HorizontalLayout>
            </layout:VerticalLayout>
    </Page>
</mvc:View>

Startpage.controller.js

    sap.ui.define(['sap/ui/demo/fiori/controllers/BaseController'], function(Controller){
                "use strict";
                return Controller.extend('sap.ui.demo.fiori.controller.Startpage',{
                        onInit:function(){
                                console.log('Startpage loaded');
                                let map = new demo.map.SimpleMap();
                                //console.log(map);
                                let oLay = this.getView().byId('layout');
                                oLay.addContent(map);
                        },
                        gotoUserList: function(){
                                this.getRouter().navTo('listUsers');
                        },
                        getRouter: function(){
                                return this.getOwnerComponent().getRouter();
                        }
                });
        });

Also, I have tried to add the map object directly from controller without custom control, but i got below error

'Map container not found' error from Leafletjs framework.

Hope someone please help me. I am pretty lost in how to render leaflet using openUI5.

2
Where are you loading the Leafletjs framework? It believe it should be loaded together with your library.fabiopagoti

2 Answers

0
votes

Ok, this is how i could get it work:

SimpleMap.js

sap.ui.define(['jquery.sap.global','sap/ui/core/Control', './library'], function(jQuery, Control, library){
        "use strict";

        let SimpleMap = Control.extend('demo.map.SimpleMap',{
            metadata:{
                library: 'demo.map',
                properties:{
                    "width":{type: 'sap.ui.core.CSSSize', defaultValue:'300px'},
                    "height":{type: 'sap.ui.core.CSSSize', defaultValue:'300px'}
                }
            }
        });

        SimpleMap.prototype._drawMap = function(){
            this.controlAspect = parseInt(300) / parseInt(300);
            /* using: L.map(this.$()).setView(...); << trown an error: 
            "Cannot read property 'baseVal' of undefined", which seems that is a jQuery object instead of a DOM element. Ref: 
            https://github.com/Leaflet/Leaflet/issues/2302 
            I couldn't how to get current DOM element.
            */
            let map = L.map('map').setView([39.7166700,-8],8);
            L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
        }

        SimpleMap.prototype.onAfterRendering = function(){
            this._drawMap();
        }

        return SimpleMap;
    }, true);

SimpleMapRenderer.js

sap.ui.define(['jquery.sap.global'], function(jQuery){
        "use strict";

        let SimpleMapRenderer = {};

        SimpleMapRenderer.render = function(oRm, oControl){
            oRm.write('<div ');
            oRm.write('id="map"'); // set it hardcoded
            oRm.writeControlData(oControl);
            oRm.addStyle('height',oControl.getHeight());
            oRm.addStyle('width',oControl.getWidth());
            oRm.writeStyles();
            oRm.write('>');
            oRm.write('</div>');
        }

        return SimpleMapRenderer;
    }, true); // notice this: last version i did not export it...

Thanks for all your help.

PS.- Instead of using oRm.write('id="map"'); << and from control how to get dom element using this.$() ? I have tried: this.$()[0] but nothing...

0
votes

The error message pretty tell you precisely the problem: Your SimpleMapRenderer.js does not define a function called render. Instead you have called it renderer, which is what it would be called if you left it inside the SimpleMap.js. (Also, see edit below, the SimpleMapRenderer object needs to be exported, i.e. you need to add a true parameter to the define() call.)

The other problem ('Map container not found' error from Leafletjs framework.) will probably reappear once you fix the function name. That happens because your drawMap function directly references an element with id 'map'. OpenUI5 however will use the Control's id. You should change your call to

let map = L.map(this.getDomRef()).setView([39.7166700,-8],8); 

That should create the map inside the div created by the ui5 renderer.

Edit: I've built the code in plnkr: http://plnkr.co/edit/BTDfwegfvO4iR4T3Mod0?p=preview It shows I should have used getDomRef() instead of $(). Fixed above. It also showed, you forgot to export the render class definition (and I didn't notice). After also adding a height to the div (and loading the css), it now properly draws a map.