Steven Scaffidi
Steven Scaffidi

Reputation: 2307

Selecting elements from the DOM - Reasonml/BuckleScript querySelector

How would you select items from the DOM using Reason. I'm using bs-webapi for the DOM bindings here is what I want to do:

let parent = document |> Document.querySelector(".parent");
let child = Element.querySelector(".child", parent);

However, BuckleScript complains because parent isn't of the right type. It says parent is of type option(Dom.element) and parent is expected to be Dom.element.t. I'm new to Reason and trying to learn. I don't understand what option(Dom.element) means or how to make something like the above code block work. Any help is greatly appreciated

Upvotes: 2

Views: 992

Answers (1)

Neil Kistner
Neil Kistner

Reputation: 12373

You need to unwrap the option variant, and we can do that with a switch and use the built-in None/Some variants.

You can find some documentation on the option variant here: https://reasonml.github.io/docs/en/newcomer-examples.html#using-the-option-type

Here is some more documentation on option: https://reasonml.github.io/docs/en/variant.html#option

To do this, you would change your code to something like this:

let parent = document |> Document.querySelector(".parent");
let child = switch (parent) {
  | Some(p) => switch (Element.querySelector(".child", p)) {
    | Some(c) => c
    | None => raise(Failure("Unable to find child selector"))
  }
  | None => raise(Failure("Unable to find parent selector"))
};

If you wanted to instead log to the console instead of fail, you would need to return a valid Dom.element.t, which could be something like this:

let emptyEl = document |> Document.createElement("noscript");
let parent = document |> Document.querySelector(".parent");
let child = switch (parent) {
  | Some(p) => switch (Element.querySelector(".child", p)) {
    | Some(c) => c
    | None => {
      Js.log("Unable to find child selector");
      emptyEl;
    }
  }
  | None => {
    Js.log("Unable to find parent selector");
    emptyEl;
  }
};

You would then want to check if your child element was a noscript to see if you found the child you were looking for.

Upvotes: 3

Related Questions