OvermindDL1

OvermindDL1

We’ve been using WebComponents a lot lately at our place of work and sadly using the phoenix socket library threaded through everything is not very reusable, so ended up making a webcomponent of the phoenix socket itself. So we can just do something like this in html:

        <phoenix-socket
          endpoint="/socket"
          param-token="<%= Guardian.Plug.current_token(@conn) %>"
          connected="{{socketConnected}}"
          socket="{{socket}}"
          connect
          ></phoenix-socket>
          EndPoint: "[[socket.endPoint]]"<br />
          IsConnected: "[[socketConnected]]"<br />

And this, in this case, outputs this to the screen:

EndPoint: "/socket/websocket"
IsConnected: "true"

Of course changing any of the properties like endpoint or parameters or disabling ‘connect’ or so will cause it to disconnect and/or reconnect with new parameters, but for a socket that is a rare case anyway.

We can continue to thread to join a topic like:

    <phoenix-channel
      socket="{{socket}}"
      channel="{{channel}}"
      topic-pre="Messenger:"
      topic="system"
      msg-joined="{{msgJoined}}"
      connected="{{topicSystemConnected}}"
      ></phoenix-channel>
    System Topic Joined:  [[topicSystemConnected]] <br />
    Your nick:  [[msgJoined.nick]]

Which outputs this (since the server "Messenger:system" topic returns a structure that contains your nick):

System Topic Joined: true
Your nick: Gabriel Robertson

The {{socket}} here is the same variable that is from the <phoenix-socket />, you can pass in the normal Phoenix library socket object as well if you are using an existing library elsewhere and want to re-use the socket, or you can take this socket and give it to normal javascript code elsewhere. And as expected if you add a sleep or something to the socket join then the ‘true’ above will be ‘false’ until the join finally goes through. It automatically handles new sockets, no sockets, sockets losing and reconnecting its connection, etc… Also handles changing properties will disconnect and reconnect to a new given topic with whatever parameters are specified as expected. You can get various topic information here (like with the socket, the channel has a lot more options that are not demonstrated here, still need to program in more as well).

To handle messages you can use javascript to listen as normal, or continue using html by doing:

<phoenix-msghandler
  channel="{{channel}}"
  key="msg:recv"
  msg="{{receivedMsg}}"
  ></phoenix-msghandler>

And similar for presence as well, takes the channel output from the above <phoenix-channel /> as input, or feel free to pass in your own channel object via javascript. Usual property stuff. Etc…

Do many other people use webcomponents here and might find these useful?

Showing Posts 1 to 5

OvermindDL1

OvermindDL1 OP

I’ve made a testing SPA that is server driven using webcomponents. The links at the top are normal ‘a’ links (middle-clickable and all), just instead of routing they are matched out and sent to the server via a <phoenix-channel-msg> element. The server sends a map of “importURLs” and “elementName” and optionally “cmds”, the SPA will import those url’s if not already imported then it will create the given element and replace the on-page ‘page’ element with (using css effect to slide out and in, just because I could ^.^) once it fully loaded. There is no flash of unstyled content, everything is fast and easily cachable and mix phoenix.digestable, all communication happens over a phoenix websocket/longpolling, tested in Chrome, Firefox, Edge (the below animation is edge, it is actually a lot smoother than the animation shows), IE11, and Chrome on my android phone:

The Root link is just “/spa”, the Root with slash link is “/spa/” (I was trying to test all cases), Messenger is “/spa/messenger”, and Blah is “/spa/blah”. Blah does not exist on the server so it sends back a thing to display the error module (which I’ve not implemented yet so it falls back to blank and logs a message in the console right now), but messenger displays another module that sets up another phoenix channel connection over the same socket, and the root’s just display the ‘home’ page, which is just some text right now. I have some descriptive text showing the state of some of the bindings.

The useful bit of the html is just this:

    <app-location route="{{fullRoute}}" url-space-regex="[[basePath]]"></app-location>
    <app-route id="baseRoute"
      route="{{fullRoute}}"
      pattern="[[basePath]]"
      tail="{{baseRoute}}"
      active="{{baseRouteActive}}"
      ></app-route>
    <app-route id="route"
      route="{{baseRoute}}"
      pattern="/:name"
      data="{{moduleRouteData}}"
      tail="{{moduleRoute}}"
      active="{{moduleRouteActive}}"
      ></app-route>

    <phoenix-socket id="socket"
      endpoint="/socket"
      param-token="[[paramToken]]"
      connected="{{socketConnected}}"
      socket="{{socket}}"
      connect="true"
      ></phoenix-socket>

    <phoenix-channel
      socket="{{socket}}"
      channel="{{controlChannel}}"
      topic="spa"
      msg-joined="{{controlChannelMsgJoined}}"
      connected="{{controlChannelConnected}}"
      ></phoenix-channel>
    <phoenix-channel-msg
      channel="{{controlChannel}}"
      event="view"
      msg-send="{{moduleRouteData.name}}"
      msg-latest="{{mainViewData}}"
      ></phoenix-channel-msg>

    <app-drawer-layout id="layout" responsive-width="1280px">
      <app-drawer swipe-open>
        <app-header condenses reveals shadow effects="waterfall">
          <app-toolbar style="pointer-events:all;">
            <a main-title href="/" class="site-title">/* Snip */</a>
          </app-toolbar>
        </app-header>
        <div style="height: 100%; overflow: auto;">Testing a drawer</div>
      </app-drawer>
      <app-header-layout>
        <app-header condenses reveals shadow effects="waterfall">
          <app-toolbar style="pointer-events:all;">
            <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
            <a main-title href="/" class="site-title">/* Snip */</a>
          </app-toolbar>
        </app-header>
        <main role="main">

          <a href="[[basePath]]">Root</a><br />
          <a href="[[basePath]]/">Root with slash</a><br />
          <a href="[[basePath]]/messenger">Messenger</a><br />
          <a href="[[basePath]]/blah">Blah</a><br />

          Token: "[[paramToken]]"<br />
          BasePath: "[[basePath]]"<br />
          Module Name: "[[moduleRouteData.name]]" -> [[_stringify(moduleRouteData)]]<br />
          Module Path: "[[moduleRoute.path]]"<br />
          Socket: "[[socket]]"<br />
          EndPoint: "[[socket.endPoint]]"<br />
          IsConnected: [[socketConnected]] -> [[controlChannelConnected]] -> [[_stringify(controlChannelMsgJoined)]]<br />
          MainViewData: [[_stringify(mainViewData)]]<br />
          ModuleRouteActive:  [[moduleRouteActive]]<br />
          <neon-animated-pages
            id="moduleContainer"
            attr-for-selected="module"
            selected=""
            on-neon-animation-finish="_onNeonAnimationFinish"
            entry-animation="slide-from-right-animation"
            exit-animation="slide-left-animation"
            animate-initial-selection></neon-animated-pages>
        </main>
      </app-header-layout>
    </app-drawer-layout>

And Phoenix is currently routing all “/spa” and “/spa/*path” requests to that same template, the router on the page uses the route to contact the server to determine what to display. I have a few modules though I’m just testing some of the test links in the animation (and removed the work branding and such).

gpb

gpb

Very cool. I’ve been learning React Native for a small mobile project, but a big-shot friend in San Francisco is pushing me to get into Polymer and WebComponents.

Would be very interested to see this up on GitHub someday.

andre1sk

andre1sk

Those are very different with React Native you are actually using native widgets. React Native is really fun to develop in compared to fully native too.

cpgo

cpgo

Can you share a public repo? This is very interesting.

OvermindDL1

OvermindDL1 OP

I plan to pull out the phoenix socket webcomponents out once I’ve finished well testing them. I seemingly keep finding random little bugs of my own doing every time I stress them, though not in over a week now so they might be good. Still some new features I want to add though, but those are pretty optional, I could release it now, hmm…

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
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