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).

Last Post!

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

hst337
Elixir compiler and language specification Purpose of the proposal Elixir language is in mature state and no breaking or heavy changes ar...
New
dkuku
This is a proposal to make the map key mismatch errors a bit better: Every time I have a typo It’s very challenging for me even when I u...
New
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
dibok
Hi, I’m trying to use phoenix.js in my Qt QML project which has it’s own buildin JavaScript engine. Problem is that (what I googled so f...
New
pejrich
I propose adding compact_map/2 to the Enum module. What is it? Sometimes you want to map over a collection, but sometimes you want to ma...
New
nunobernardes99
On 1.8+, when we generate an authentication system with mix phx.gen.auth we can make use of magic link login which is amazing and a great...
New
ffloyd
The Problem Currently, if I define a struct in the following way: defmodule MyStruct do # Both x and y will have the FIXED values unti...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement