Having issue of rendering Mapbox map from any ID other than "app"

456 views Asked by At

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.

1

There are 1 answers

0
Ian Wilson On

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 the oncreate(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 mithril view method. I think what is happening is that the initialization code runs before the dom element is ready and therefore the Container 'map' not found error occurs.

Documentation for the oncreate method: oncreate

Mithril 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.