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
benkimpel
Background I work at a hedge fund and our traders need highly dynamic UIs (think splitters, tabbed panels, tree lists, enormous data grid...
New
Oliver
One common problem we face in constructing lists is that there is (AFAIK) no support for conditionally inserting members into list declar...
New
altdsoy
Hi there :wave:, I hope everyone is doing well… Tl;Dr: Is there a use case to have Heroicons from an actual hex.pm package instead of G...
New
cortfritz
Each time i use phx.gen I end up adding dark mode to it. I’m offering to add this to the default phx gen templates. This would use ta...
New
Redbaritone
In the current Auth code, the email must change to be valid. This may be true for the two situations the author has in mind: Registering ...
New
cevado
I was reading the EEP-79, and thinking about the poor record support in Elixir(i’ve tried to discuss about that in the forum before). I s...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36654 110
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31494 112
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
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement