dkuku

dkuku

Importing external js works only in a callback function

Js is not my strongest skill and I can’t find this in the kino examples.
Every time I wan’t to include js it only works for me inside a callback function that I pass to the promise. With one included file it’s fine but with multiple it becomes tricky.
Importing on top of the file does not work with every kind of js file like in the mermaid example.
If I try to import the url that is provided in the importJS in the example below it throws an error in the js.
I tried the same with pev2 package and I have similar problem there.

defmodule VlBlockly do
  use Kino.JS

  def new(toolbox) do
    Kino.JS.new(__MODULE__, toolbox)
  end

  asset "main.js" do
    """
    const blockyRoot = '<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>'
    export function init(ctx, toolbox) {
        ctx.importJS("https://unpkg.com/blockly/blockly.min.js").then(() => {
            load(ctx, toolbox)
        })
    }
    const load = (ctx, toolbox) => {
        ctx.root.innerHTML = blockyRoot;
        const workspace = Blockly.inject('blocklyDiv', {toolbox: JSON.parse(toolbox)});
    }
    """
  end
end
toolbox =
  %{
    contents: [
      %{kind: "block", type: "text"},
      %{kind: "block", type: "text_print"}
    ],
    kind: "flyoutToolbox"
  }
  |> Jason.encode!()

VlBlockly.new(toolbox)

Marked As Solved

jonatanklosko

jonatanklosko

Creator of Livebook

@dkuku so the confusion is around importing multiple dependencies with importJS? You could import the second file inside the callback, but to avoid nesting you can do async/await. Like this:

defmodule VlBlockly do
  use Kino.JS

  def new(toolbox) do
    Kino.JS.new(__MODULE__, toolbox)
  end

  asset "main.js" do
    """
    export async function init(ctx, toolbox) {
      await ctx.importJS("https://unpkg.com/blockly/blockly.min.js");
      // await ctx.importJS(...);
      
      ctx.root.innerHTML = `
        <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
      `;
      
      const workspace = Blockly.inject('blocklyDiv', { toolbox });
    }
    """
  end
end

toolbox = %{
  contents: [
    %{kind: "block", type: "text"},
    %{kind: "block", type: "text_print"}
  ],
  kind: "flyoutToolbox"
}

VlBlockly.new(toolbox)

If you run into any errors, please include those : )

Sidenote, you don’t need to use Jason, the payload is automatically serialized and deserialized!

Importing on top of the file does not work with every kind of js file like in the mermaid example

Yeah, it depends on how the package is distributed. Top-level import works fine for ES modules, but some packages expect to be loaded via <script> tag, which is exactly what importJS does.

In more complex cases you can also consider using a JS bundler as in a regular JS project.

Where Next?

Popular in Questions Top

greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
nobody
Hi! In PHP: $SERVER['SERVERADDR'] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New

Other popular topics Top

chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43591 214
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52238 488
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement