Need help with live posting and reloading in index view

newbular questions.

Q: I need to have some guidance on Phoenix’s internal for sending a database save and reloading its data.

I generated a view and the database migration.
The app requires a live like view and database store.
It has a global javascript object in the index view with a button to send data the some of the global object to the database.

After it saves it should reload a div to the right with all of the table records.

More Details:
The app is a Canvas Painting element that writes its indexes to an array with the schema
{name :string, dataarray: }
dataarray is either an int array larger than 256 characters
Or its a string comma separated of characters length * 2
example [0,1,0,1,1,1,…] or “1,1,1,10,0,1,01,0”
Its a painting Mask from a grid unit.

Anyway, each painting image is saved to a database and reloaded and processed to build an <img > and stacked into a div on the page

Work ive done:

I have tried LiveView to send a random database save.

For LiveView I have a simple function button. It saves arbitrary data, which is good. But it refuses to reload the view then when I have the Jason.encode line in the template file below

def handle_event("quicksave", _value, socket) do
  socket = update(socket, :count, &(&1 + 1))

  current_count = socket.assigns.count
  
  changeset = Painting.changeset(%Painting{}, %{name: "hiya", dataarray: "1,2,3,4,5" })
  
  case Repo.insert(changeset) do
    {:ok, _painting} ->
    
      painting_records = Repo.all(Painting)

      socket = assign(socket, :painting_records, painting_records)
      
      {:noreply, socket}

    {:error, _changeset} ->
      {:noreply, socket}
  end
end

However in the index.html.heex files to reload the images I get fighting issues trying to encode the data to parse later. Note I found this code from chatgpt with tweaks to get error messages to go away enough

<div id="images" phx-hook="LoadPaintItems" data-paintitems={ Jason.encode!(@streams.paintitems) }>?</div>

hook

export const LoadPaintItems = {
  mounted() {
    const imagesDiv = document.querySelector("#paintingblock #images");
    const paintItems = this.el.dataset.paintitems ? JSON.parse(this.el.dataset.paintitems) : [];
    paintItems.forEach(item => {
      const itemElement = document.createElement("p");
      itemElement.textContent = `Name: ${item.name}, Dataarray: ${item.dataarray.join(", ")}`;
      imagesDiv.appendChild(itemElement);
    });
  }
};

So I then tried the standard non LiveView controller. For these I cant even get it to submit the database save

def fast_add(socket, _params) do
  # uuid = Ecto.UUID.generate()
  data = %{id: 0, name: "namey", dataarray: "2,3,4,5"}
  # Othertry.create_othertry(data)
  # conn
  # |> put_flash(:info, "Data added successfully!")
  # |> redirect(to: Routes.othertry_path(conn, :index))
  
    case Repo.insert(data) do
      {:ok, oOthertry} ->
        
        othertry_collection = Repo.all(Tacos2)
        
        socket = assign(socket, :othertry_collection, othertry_collection)

        {:noreply, socket}
  
      {:error, _changeset} ->
        # Handle the error case
        {:noreply, socket}
    end
end

index.html.heex

    <.link href={~p"/othertry/new"}>
      <.button>fast Save</.button>
    </.link>

routes

post "/fast_add", OthertryController, :fast_add

live "/paintitems", PaintItemLive.Index, :index
live "/paintitems/new", PaintItemLive.Index, :new
live "/paintitems/:id/edit", PaintItemLive.Index, :edit

live "/paintitems/:id", PaintItemLive.Show, :show
live "/paintitems/:id/show/edit", PaintItemLive.Show, :edit

I will try recreating the errors, I broke the app pretty hard and will prob just make a new one and try again

Non Live view error on save

deps/ecto/lib/ecto/repo/queryable.ex:477: value `"fast_add"` in `where` cannot be cast to type :id in query:
from t0 in Phe.Paintings,
  where: t0.id == ^"fast_add",
  select: t0

Hi @ofwhatisabookinthebo, and welcome to the forums!

There are a few moving parts there - and it’s hard to know where to start tbh. If there isn’t anything proprietary or confidential, your best option is to put the broken code up on GitHub.

Otherwise, my advice would be to break it down into steps…

  1. Can you save and retrieve data separate from web interface?
  2. Can you render any image as you expect, separate from database and interactivity?
  3. Can you may the image update by other means (i.e. separate from the save)?
    etc

A couple of things I did notice

  1. Your JS hook probably needs an updated() as well as a mounted() to ensure it reacts to changes to the socket assigns.
  2. Have you confirmed your non-LiveView controller code is getting called (e.g. put a few IO.inspect calls through it to see what’s happening)

rebuilt project, solved it, but not perfectly, will post a github about it.

Deployed on gigalixir !

here are the main parts

In these you can see how I was just jamming in fetches to force live loads. Its not like LiveView for sure and I know it goes against the goodness that elixir gives, but it mostly worked.
I had to remove the .then(response) promises cause they would return html instead of json so it was breaking the app.

And {Jason.encode!(@paintings)} I could not get it to load in the script tag at all so had to resort to dropping it into a dom element. And the data in is massive in character counts. But html spect allows it so wutevr

chatgpt still give examples of `<%= … %> but those all failed when trying to use