dkuku

dkuku

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)

Showing Posts 1 to 5

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.

dkuku

dkuku OP

Thanks for the hints :+1:

dkuku

dkuku OP

@jonatanklosko
I wonder if having a html asset would not make things easier here? Then the scripts can be embedded directly in the html. rit would be easier to mirror the examples from the web. Building the initial root layout could be also simplified.

jonatanklosko

jonatanklosko

Creator of Livebook

@dkuku there is Kino.HTML for some range of use cases, but most of the time we use the JS init function as an entry point, because it receives data from the Elixir side.

adolfont

adolfont

This thread was very useful.
I was also able to use p5.js (a JavaScript library for creative coding) inside Livebook. In really don’t know if I can do much more than that.

https://twitter.com/adolfont/status/1655554171867627521

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews