What is a Phoenix JavaScript view and how to properly use one?

I found this in the default Phoenix layout_view.ex and it seems potentially relevant to some problems I’ve been trying to solve. As such, could someone explain what the code here:

  @doc """
  Generates name for the JavaScript view we want to use
  in this combination of view/template.
  """
  def js_view_name(conn, view_template) do
    [view_name(conn), template_name(view_template)]
    |> Enum.reverse
    |> List.insert_at(0, "view")
    |> Enum.map(&String.capitalize/1)
    |> Enum.reverse
    |> Enum.join("")
  end

means, and also the comment? At the moment all I’m really seeing is some reversals, enumerations and joins. It seems like this code is responsible, at least partly, for the name of the app prefixed file that’s created by default by Phoenix, and understanding this might be the key to genuine per-page JavaScript loading in Phoenix.

1 Like

It extracts the name of the view from conn and the templates name from view_template and puts both in a list [view, template]

This list is reversed then: [template, view]

"view" is inserted at the front: ["view", template, view]

Everything is capitalized: ["View", cap_template, cap_view]

Reversed again: [cap_view, cap_template, "View"]

And joined: "#{cap_view}#{cap_template}View"

Perhaps the following is easier to read for you, perhaps it is not, but both is equivalent:

def js_view_name(conn, view_template) do
  "#{conn |> view_name |> String.capitalize}#{view_template |> template_name |> String.capitalize}View"
end

But to be honest, I’m not sure what this function does, or how it can be used. I haven’t used it actively so far.

4 Likes

I think perhaps the best option might be to inject it into other views and see what it does there, though I’m not yet 100% sure of which tests to run. It’s kinda difficult to do senior developer stuff off 3 years freelance experience, but right now I’ll kinda have to :/.

1 Like

A while back I too was searching for a technique to load individual modules, one for each view, as the user visited each page.

This looks like code that I found in my investigations (through Google) and it is intended to generate a string to create an identifier for the current view. In the schemes I read about, that string could be used to invoke view-specific JavaScript. IIRC the string generated was either used directly as a filename to load, or as a key into an associative array matching strings to JavaScript classes.

When using the identifier as a filename, you had two other problems. First you had to get your JavaScript separated out into different files in the runtime server’s directory tree. At the time, Brunch came configured, by default, to compile all your JavaScript down to the app.js file. IIRC you had to switch bundlers to solve that problem. Secondly, only some JavaScript module schemes supported file-based includes at runtime. I can’t remember if the bundler played a role in whether that was possible or not.

When used as a key into a table of classes, the article should give a little framework with a base class that your view-specific Java module must derive from. You would then write a class per view and compile it into app.js and you would add the class name to a table indexed by the string a function like this generated. At runtime you would retrieve the class and invoke it based on the current view.

3 Likes

Diacode:
Page specific JavaScript in Phoenix framework (pt.1 - Brunch, ES6)
Page specific JavaScript in Phoenix framework (pt. 2 - Webpack)

1 Like

To be clear, Phoenix does not generate this code and does not have an idea of a “JavaScript View”, so this code must have been added by a collaborator for js related features.

3 Likes