gleam

How to write external function to call method invocation while compiling gleam code to JavaScript?


I am trying to write the Gleam JavaScript binding for basic DOM manipulation. I want to achieve following JavaScript functionality with gleam:

const div = document.createElement('div');

div.classList.add('className');

I am writing following external definition:

pub external type Document

pub external type HTMLElement

pub external fn create_elm(String) -> HTMLElement =
  "" "document.createElement"

// HOW TO WRITE FOLLOWING EXTERNAL DEFINITION
pub external fn add_class(HTMLElement, String) -> Nil =
  "" "$0.classList.add"

So, for add_class function, I want gleam to compile to JS such that first argument HTMLElement is used as a object and second argument String is passed to the some method of the HTMLElement. How to achieve this?

I could not find any documentation for this on gleam website. I thought something like the way Fable allows writing external binding would be possible. However, that doesn't work.


Solution

  • Gleam doesn't have any functionality for working with OOP JavaScript so in this case I would use some JavaScript glue code.

    // in src/app.gleam
    
    pub type Document
    
    pub type HTMLElement
    
    @external(javascript, "./app_ffi.mjs", "createElement")
    pub fn create_elm(kind: String) -> HTMLElement
    
    @external(javascript, "./app_ffi.mjs", "addClass")
    pub fn add_class(el: HTMLElement, class: String) -> Nil
    
    // in src/app_ffi.mjs
    
    export function createElement(kind) {
      return document.createElement(kind)
    }
    
    export function addClass(element, string) {
      element.classList.add(string)
    }