nallwhy

nallwhy

Doumi.Phoenix.Params - A helper library that supports converting form to params and params to form

Doumi.Phoenix.Params is a helper library that supports converting form to params and params to form.

It is still confusing to handle Ecto.Changeset, Phoenix.HTML.Form for form binding.

For example,

To make it easy and straightforward, I’ve made Doumi.Phoenix.Params.

defmodule MyAppWeb.TestParams do
  use Ecto.Schema
  import Ecto.Changeset

  @primary_key false
  embedded_schema do
    field :foo, :string
  end

  @required [:foo]
  def changeset(%__MODULE__{} = struct, attrs) do
    struct
    |> cast(attrs, @required)
    |> validate_required(@required)
  end
end

defmodule MyAppWeb.MyLive do
  use MyAppWeb, :live_view
  alias MyAppWeb.TestParams
  alias Doumi.Phoenix.Params

  ...

  @impl true
  def mount(_params, _session, socket) do
    # Without Doumi.Phoenix.Params
    # form =
    #   TestParams.changeset(%TestParams{}, %{})
    #   |> to_form(as: :test)

    # With Doumi.Phoenix.Params
    form = Params.to_form(%TestParams{}, %{}, as: :test, validate: false)

    socket = socket |> assign(:form, form)

    {:ok, socket}
  end

  @impl true
  def handle_event("validate", %{"test" => test_params}, socket) do
    # Without Doumi.Phoenix.Params
    # form =
    #   TestParams.changeset(%TestParams{}, test_params)
    #   |> to_form(as: :test)
    #   |> Map.put(:action, :validate)

    # With Doumi.Phoenix.Params
    form = Params.to_form(%TestParams{}, test_params, as: :test)

    socket = socket |> assign(:form, form)

    {:noreply, socket}
  end

  @impl true
  def handle_event("change_foo_from_outside_of_form", %{"foo" => foo}, socket) do
    # Without Doumi.Phoenix.Params
    # test_params =
    #   socket.assigns.form.source.params
    #   |> Map.put(%{"foo" => foo})
    #
    # form =
    #   TestParams.changeset(%TestParams{}, test_params)
    #   |> to_form(as: :test)
    #   |> Map.put(:action, :validate)

    # With Doumi.Phoenix.Params
    test_params =
      socket.assigns.form
      |> Params.to_params(%{"foo" => foo})

    form = Params.to_form(%TestParams{}, test_params, as: :test)

    socket = socket |> assign(:form, form)

    {:noreply, socket}
  end

  @impl true
  def handle_event("save", %{"test" => test_params}, socket) do
    # Without Doumi.Phoenix.Params
    # test_params_map =
    #   TestParams.changeset(%TestParams, test_params)
    #   |> Ecto.Changeset.apply_changes()
    #   |> some_how_change_nested_struct_to_map_if_you_use_map_with_atom_key()

    # With Doumi.Phoenix.Params
    test_params_map =
      Params.to_form(%TestParams{}, test_params)
      |> Params.to_map()

    :ok = TestDomain.create_test(test_params_map)

    {:noreplym, socket}
  end

  ...
end

Most Liked

nallwhy

nallwhy

v0.3.0 is released!

Now it provides use Doumi.Phoenix.Params, opts... that creates handy to_form/2 to the schema module.

defmodule MyAppWeb.TestParams do
  use Ecto.Schema
  use Doumi.Phoenix.Params, as: :test # <--- with use macro

  ...
end

defmodule MyAppWeb.MyLive do
  ...

  @impl true
  def handle_event("validate", %{"test" => test_params}, socket) do
    # Without Doumi.Phoenix.Params
    # form =
    #   TestParams.changeset(%TestParams{}, test_params)
    #   |> to_form(as: :test)
    #   |> Map.put(:action, :validate)

    # With Doumi.Phoenix.Params
    # form = Params.to_form(%TestParams{}, test_params, as: :test)

    # With use Doumi.Phoenix.Params
    form = TestParams.to_form(test_params) <--- much easier

    socket = socket |> assign(:form, form)

    {:noreply, socket}
  end
end

Thank you for reading it!

Where Next?

Popular in Libraries Top

hpopp
After just over two years in development, this latest version of Pigeon is what I finally consider done in regards to my original vision ...
New
zoltanszogyenyi
Hey everyone :wave: Excited to join this forum - I am one of the founders and current project maintainers of a popular and open-source U...
New
nikokozak
Hello all, I’ve been working on Svonix - a library for quickly integrating Svelte components into Phoenix views. It’s a much-needed succ...
New
woutdp
Hi! I wanted to introduce my latest project LiveSvelte. It allows you to render Svelte inside LiveView with end-to-end reactivity. It’s ...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
blatyo
https://www.conduitframework.com/ The best overview for how things are tied together is this presentation. Modules and functions are pre...
New
Crowdhailer
Experimenting with this code. OK.try do user &lt;- fetch_user(1) cart &lt;- fetch_cart(1) order = checkout(cart, user) save_or...
New
mtrudel
Bandit is an HTTP server for Plug and WebSock apps. Bandit is written entirely in Elixir and is built atop Thousand Island. It can serve...
New
mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story &lt;- Meeseeks.all(html, css("tr.athing")) do...
New
wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

Sub Categories:

We're in Beta

About us Mission Statement