I'm trying to implement Mapbox gl gs into a project I'm building with Mithril and am having issues with getting a map to render from any ID other then "app". Within the body of my html I have a div called app so it makes sense why that works. The problem is, I dont want the map to be rendered both from the initial app location and from the location I want it to be rendered from in my case "map".
html
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<!-- bootstrap -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"
integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ"
crossorigin="anonymous"></script>
<!-- google fonts -->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Caudex:wght@700&family=Rock+Salt&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://fonts.gstatic.com">
<!-- mapbox -->
<script src='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css' rel='stylesheet' />
<title>NoN</title>
</head>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"></script>
</body>
</html>
and my current Map Component:
const m = require("mithril");
import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = MAPBOXTOKEN
let map = new mapboxgl.Map({
container: 'app', // container id
// container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v11', // style URL
center: [-74.5, 40], // starting position [lng, lat]
zoom: 9 // starting zoom
});
const Map = {
view: (vnode) => (
<div>
<div id="app"></div>
</div>
)
}
export default Map
I would like to be rendering only from the div with the id "map" like so:
const m = require("mithril");
import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = 'pk.eyJ1IjoiZG10cmVlcyIsImEiOiJja2w4ZHN0NzEyMHI0MzJxbTNuOW56YXlsIn0.jNw5dh1j09irmOYBCTykAg'
let map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v11', // style URL
center: [-74.5, 40], // starting position [lng, lat]
zoom: 9 // starting zoom
});
const Map = {
view: (vnode) => (
<div>
<div id="map"></div>
</div>
)
}
export default Map
but when doing so I get this error:
VM472725 bundle.js:1642 Uncaught Error: Container 'map' not found.
This question is a problem similar to this question because it involves integrating a 3rd party widget with Mithril: Question #62924959
You need to place the map initialization code,
let map = new mapboxgl.Map(...)inside theoncreate(vnode)method of the mithril component. Then you can either pass the dom element directly with vnode.dom or use the id of whatever you set in the mithrilviewmethod. I think what is happening is that the initialization code runs before the dom element is ready and therefore theContainer 'map' not founderror occurs.Documentation for the
oncreatemethod: oncreateMithril has the following example code when using a 3rd party tool (ie. not aware of mithril's re-rendering, etc.): 3rd party integration
To make your code more re-usable you could use a dynamic id on the dom element and use that in the oncreate method to pass to the map intialization code.