DaAnalyst

DaAnalyst

Can we get support for colocating shared JS constants with a group of otherwise colocated JS components?

@chrismccord @josevalim @steffend

Been using colocated JS for a while and I keep on stumbling on the same limitation: there is no way (at least known to me) to colocate JS constants with a group of custom elements operating together as a whole (naturally, each defined is in its own file/script module).

I managed to import them (from one script module into another) but they can only be used from connectedCallback on. They don’t exist yet (synchronously) right after the import statement nor can they be used directly or via a function call in the Lit decorators like @provide, @consume and friends, i.e. they cannot be used as constants.

I know it works by simply moving those constants to a .js file and saving it in assets, but that’s no longer a “physical” colocation and those constants are of no concern to the rest of the app.

Is there any chance this could be somehow added to Phoenix/LiveView?

Thanks

Marked As Solved

steffend

steffend

Phoenix Core Team

I see the problem now (note that it would have been much easier if you posted the exact kind of error you’re seeing). Because of the way the JS files are bundled by esbuild, the individual modules are put before the code that initializes the key variables.

The solution to that is to use a different manifest for constants:

  @doc false
  def __colocated_constants__(assigns) do
    ~H"""
    <script :type={Phoenix.LiveView.ColocatedJS} name="SharedFoo" manifest="constants.js">
      const constants = {
        FOO: "foo",
        BAR: "bar",
      }
      export default constants;
    </script>
    """
  end

  def my_component(assigns) do
    ~H"""
    <script :type={Phoenix.LiveView.ColocatedHook} name=".MyHook">
      import constants from "phoenix-colocated/my_app/constants";

      console.log(constants.SharedFoo.FOO);

      export default {
        mounted() {
          this.el.innerText = JSON.stringify(constants.SharedFoo);
        }
      }
    </script>

    <div id="some-id" phx-hook=".MyHook"></div>
    """
  end

Also Liked

steffend

steffend

Phoenix Core Team

You can do something like this:

defmodule MyAppWeb.SomeComponent do
  @doc false
  def __colocated_constants__(assigns) do
    ~H"""
    <script :type={Phoenix.LiveView.ColocatedJS} name="SharedFoo" key="constants">
      const constants = {
        FOO: "foo",
        BAR: "bar",
      }
      export default constants;
    </script>
    """
  end

  def my_component(assigns) do
    ~H"""
    <script :type={Phoenix.LiveView.ColocatedHook} name=".MyHook">
      import { constants } from "phoenix-colocated/my_app";

      export default {
        mounted() {
          this.el.innerText = JSON.stringify(constants);
        }
      }
    </script>

    <div id="some-id" phx-hook=".MyHook"></div>
    """
  end
end

In this example, the constants are available as constants.SharedFoo:

// constants
{"SharedFoo":{"FOO":"foo","BAR":"bar"}}

PS: No need to ping us individually, I’m subscribed to the Proposals section.

steffend

steffend

Phoenix Core Team

Yeah it builds just fine, but I assume you got an exception in the browser like

Uncaught TypeError: can't access property "SharedFoo", imp_mnxw443umfxhi4y is undefined

That would already have put me on the right track :slight_smile:

Anyway, please report back if you find any other issues!

DaAnalyst

DaAnalyst

Yep, it works! Thank you so much for this one. You’ve got a lunch from me if you ever come visit Pula, Croatia (or any other place in the region of Istria).

Where Next?

Popular in Proposals: Ideas Top

markevans
Hi! I feel like Phoenix is slightly missing a trick when it comes to front-end Javascript libraries like React, Svelte, etc. I feel tha...
New
moacirbishopcamata
Good morning to the Elixir team. Please excuse me if I’m commenting in the wrong place; please indicate where I should discuss this. I ...
New
snofang
In a typical business development task, having a function in a context module which accepts attributes of map type and passes them to Ect...
New
sezaru
When writing my code, I always find __MODULE__ very useful to use as alias of that module “inner dependencies”, ex: alias __MODULE__.{Im...
New
mythicalprogrammer
Hello, since the 1.8rc0 was out, DaisyUI was noted to have the benefit of light and dark mode. From the elixir subreddit, it seem a few ...
New
pelopo
Hi, Oficial docs got this wonderful feature to download the ePub version that we can chuck to our kindles and read it. Now we are in the...
New
zachdaniel
Something we do in various Ash packages is provide routes that the user forwards to in their own application. This is because we are deri...
New
mortenlund
Hi! Suggest to add the ability to do use the components socket as input into Phoenix.LiveView.send_update/3 function to make it easier t...
New
sevensidedmarble
I have a very simple suggestion: the generated config/dev.exs file should read from PORT at compile time to set the endpoints port. If ...
New
hst337
iex&gt; map = %{x: 1} iex&gt; map.x 1 iex&gt; map.x() 1 Why would anyone use the map.x() syntax for getting map value? I’d suggest depre...
New

Other popular topics Top

skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
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
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36432 110
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 127536 1222
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

We're in Beta

About us Mission Statement