How to Show the Rating Form
Learn how to perform event handling in stateful components.
We'll cover the following...
Our rating form will display the form and manage its state, validating and
saving the rating. We’ll need to pass a product and user for our relationships,
and also the product’s index in the parent LiveView’s socket.assigns.products
. We’ll use this index, later on, to update SurveyLive
state efficiently.
Building the rating form component
The component will be stateful, and we’ll need to use update/2
to stash our rating and changeset in the socket. We create a new file, pento/lib/pento_web/rating_live/form_component.ex
and define a component, PentoWeb.RatingLive.FormComponent
.
Then, we enter this update function:
defmodule PentoWeb.RatingLive.FormComponent douse PentoWeb, :live_componentalias Pento.Surveyalias Pento.Survey.Ratingdef update(assigns, socket) do{:ok,socket|> assign(assigns)|> assign_rating()|> assign_changeset()}end...end
These reducer functions will add the necessary keys to our socket.assigns
. They’ll drop in any assigns
that our parent sends, add a new Rating
struct, and finally establish a changeset for the new rating. Here’s a closer look at our “add rating” and “add changeset” reducers we add in pento/lib/pento_web/live/rating_live/form_component.ex
:
def assign_rating(%{assigns: %{user: user, product: product}} = socket) doassign(socket, :rating, %Rating{user_id: user.id, product_id: product.id})enddef assign_changeset(%{assigns: %{rating: rating}} = socket) doassign(socket, :changeset, Survey.change_rating(rating))end
There are no surprises here. One reducer builds a new rating, and the other uses the Survey
context to build a changeset for that rating.
Now, on to rendering.
Rendering the component
With our socket established, we’re ready to render. As usual, we’ll ...