How to pass a JSONB object (string) to a JSONB (map) database field from new/edit form?

How to save data like this in the database:

{  
   "1":"one",
   "2":"two"
}

from the new/edit forms? When I write this: {"1":"one","2":"two"} in the form field I get invalid data error.

Can you show the code that you have?

EDIT: Although I’ll note that Ecto :map fields expect to be given an Elixir map not a JSON string.

@benwilson512 … I have not written any special code for this yet. I simply tried to pass: {"1":"one","2":"two"} in the form field.

If it’s an HTML based form then you’ll need to actually parse that JSON in the controller body.

1 Like

Is that the proffered way to do it, inside the controller?

I tried to parse the string as JSON using Poison but could not find out how to modify the attributes before submitting them to the create changeset function. I got this error:

cannot invoke remote function Access.get/2 inside match

Because of this:

  def create(conn, %{"entity" => entity_params}) do
    attrs["mcm"] = Poison.Parser.parse!(~s(#{mcm})) <----------- error here..
    case Entities.create_entity(entity_params) do
      {:ok, entity} ->
        conn
        |> put_flash(:info, "Entity created successfully.")
        |> redirect(to: entity_path(conn, :show, entity))
      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end

@acrolink entity_params is a map, so you’ll want to use the Map.update/1 function. I’d show how but it’s probably worth giving that a shot first yourself, map update functions are fundamental in Elixir so it’s important to grasp well.

3 Likes

:sunglasses: Time to learn it, thank you :slight_smile:

Done this way:

entity_params = Map.put(entity_params, "mcm", Poison.Parser.parse!(entity_params["mcm"]))

1 Like

That definitely works! You can also

entity_params = Map.update!(entity_params, "mcm", &Poison.decode!/1)
2 Likes