_toni

_toni

LiveView. Implementing a Shopping Cart Component. How to load state from localStorage and forward it to Components

Hello :wave:

I’m trying to implement something similar to a shopping cart.
I’ve got two LV.

  • Page LV
  • SecondPage LV

They both need to render the CartComponent (in the future a full-featured cart, right now only a %{ total: X}.
The component is stateful and handles the events (see component-click event within CartComponent).

I originally followed this very interesting thread regarding not un-mounting components upon a LV change via routing, however I couldn’t make the proposed solution work. Regardless I’m giving it a try via localStorage instead, so I figure that’s a different solution.
My goal is by steps:

  1. User lands in either of the LVs (which make use of CartComponent)
  2. JS hooks load localStorage.shoppingCart --> forward it to LV
  3. LV receives the socketParams and forwards it to the CartComponent whose update re-renders with new value.
  4. Whatever new event in the cart logic --> CartComponent handles it and it is appropriately updated.

The problem I’m encountering is with the first render of all. Something like this happens.

  1. User lands in PageLive --> renders CartComponent with empty shoppingCart
  2. Second time PageLive is mounted when the connected?(socket) is true --> receives new shoppingCart from JS hook.
  3. CartComponent's update does fire and receives the updated shoppingCart post-socket connected.
  4. CartComponent's UI render does not update
  5. Manually try to fire a component-click event --> CartComponent handles and UI is properly updated.

This is the very test repo i’m running


Am I missing something to make that first update re-render?

Thanks!

Marked As Solved

outlog

outlog

your example is a bit broken - the js breaks, when localstorage is empty fix:
shoppingCart: JSON.parse(localStorage.shoppingCart || null) || "{}",

now when decoding the json you’ll get a map - not a struct…
so change the render in cartcomponent to Map.get(assigns.shoppingCart, "total")

notice “total” vs :total

likewise when you update do it in a map:

    shoppingCart = %{
      "total" => Enum.random(10..1000)
    }

this code is broken elixir

shoppingCart = %{}

if connected?(socket) do
  IO.puts("Component connected")
  shoppingCart = Jason.decode!(Map.get(assigns.socketParams, "shoppingCart"))
end

do:

shoppingCart = if connected?(socket) do
  IO.puts("Component connected")
  Jason.decode!(Map.get(assigns.socketParams, "shoppingCart"))
else
  %{}
end

also wrap your value in a html element (liveview needs this)

<div><%= Map.get(assigns.shoppingCart,"total") %></div>

then it should work…

ps: made a fork with the fixes if anybody finds this thread… https://github.com/petermm/component-test

Also Liked

Exadra37

Exadra37

This is client side storage, and you cannot trust it, therefore I am not fan of using the browser local storage for storing data.

So my advice is for you to figure out how you can make it work properly via backend, and not not via browser local storage.

Sorry not be able to help you with your way, but I am also new to Live View.

_toni

_toni

Thank you @outlog your answer helped me debug the specific problem communicating
LiveView -> LiveComponent :slightly_smiling_face:

In parallel I also tried to solve a tangential problem here, which tries to have a common source of truth for all LVs that will consume the shoppingCart (basically I wanted to keep the localStorage-resumed shoppingCart in memory so every newly mounted LV could consume it without having to resume form localStorage again). Unfortunately I couldn’t land it in the way I intended, but I think I’m overcomplicating things so I’ll pivot my approach.
Regardless that’s a different story.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
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
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement