When using bs.val how to deal with undefined?


[@bs.val] external envPort: string = “process.env.PORT”

How do I test if envPort is undefined?

Normally I would do const PORT = process.env.PORT || 9000 but that doesn’t work in ReasonML

I know I can also use https://bucklescript.github.io/bucklescript/api/Node.Process.html but the problem is more how one would do it if they had to. And right now if you google it, there is no good results.


EDIT: An example of how to get a port if defined.

let port = switch(Js.Dict.get(Node.Process.process##env, "PORT")) {
  | Some(string) => string
  | None => "9000"


This is how I usually bind to nullable global vars:

[@bs.val][@bs.scope "process.env"] external port: Js.Null_undefined.t(int) = "PORT";
let port: option(int) = Js.Null_undefined.toOption(someVar);

With a default option it can be:

[@bs.val][@bs.scope "process.env"] external port: Js.Null_undefined.t(int) = "PORT";
let port: int = port->Js.Null_undefined.toOption->Belt.Option.getWithDefault(9000);

If you want to avoid the implicit coercion then you just use string instead of int and then use your favorite type conversion method to parse the the int


Thank you, that is really useful, thank you @scull7

I got this to compile, but can’t figure out if it is still wrong?

[@bs.val] external envPort: option(string) = "process.env.PORT"

let port = switch(envPort) {
  | Some(string) => string
  | None => "9000"


looks like your code compiles down to:

var match = process.env.PORT;
var port = match !== undefined ? match : "9000";

So if you’re confident about process.env being an object then it should be ok.

Heres my scratch pad:


Your binding looks fine. Note that BuckleScript already provides bindings for some Node things, e.g. https://bucklescript.github.io/bucklescript/api/Node.Process.html

let port = "PORT"
  |> Js.Dict.get(Node.Process.process##env)
  |> Js.Option.getWithDefault("9000");

Really a matter of your preference, whether to write your own specialized bindings or stick with the provided bindings.


@scull7 Thank you, awesome!

@yawaramin Yeah I found that, I posted it later in the original post, took me a bit to understand Js.Dict.get

Looks pretty great with getWithDefault :+1:

I hope that other people can find this thread now :smiley:

Reading Env Variables with Reason and/or Reason-Scripts