How do you create mutable external value?


#1

Hi there! I would like to create ReasonML bindings for a mapbox-gl package. Mapbox requires an accessToken to be provided before you can use a library. The proper way to provide this token is to set accessToken on mapbox-gl import.

import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = '...';

I’ve created following bindings:

[@bs.module "mapbox-gl"] [@bs.val]
external accessToken: ref(string) = "accessToken";

But then I try to set accessToken with

MapboxGL.accessToken := "...";

I’m getting Uncaught TypeError: Cannot set property '0' of null. Am I missing something?


#2

I often find that looking at the generated javascript is super useful in situations like these. I just ran it through bucklescript and got

var MapboxGl = require("mapbox-gl");

MapboxGl.accessToken[0] = "...";

See, ref's are represented at runtime as an array of length 1, so “setting the contents” of a ref is e.g. theref[0] = 5.

Here’s what I would recommend:

type mapboxGlModule;

[@bs.module]
external mapboxGl: mapboxGlModule = "mapbox-gl";

[@bs.set]
external setAccessToken: (mapboxGlModule, string) => unit = "accessToken";

setAccessToken(mapboxGl, "something");

which produces the javascript:

var MapboxGl = require("mapbox-gl");

MapboxGl.accessToken = "something";

/*  Not a pure module */

#3

Oh, wow! Thanks, @jaredly!

I’m still new to ReasonML, where can I find generated javascript for a module? Consider this bsconfig.json:

{
  "name": "reason-react-mapbox-gl",
  "reason": {
    "react-jsx": 2
  },
  "sources": {
    "dir": "src",
    "subdirs": true
  },
  "package-specs": [
    {
      "module": "es6",
      "in-source": true
    }
  ],
  "suffix": ".bs.js",
  "namespace": true,
  "bs-dependencies": ["reason-react"],
  "bsc-flags": ["-bs-super-errors"],
  "refmt": 3
}

MapboxGL.bs.js contains only this

// Generated by BUCKLESCRIPT VERSION 4.0.7, PLEASE EDIT WITH CARE


var $$Map = /* module */[];

export {
  $$Map ,
  
}
/* No side effect */

#4

Oh, I got it. It was all in the compiled module I use for debug :slight_smile: