Updating deeply nested elixir maps
- 1 minutes read - 141 wordsIn some cases it is necessary to update a deeply nested attribute in a map. I went searching for a way to do this and came across several approaches, the one that worked for me was this, a combination of Kernel.put_in and Access.key, here I’m using it to update a socket struct nested assigns map.
put_in(socket, Enum.map([:assigns, :beacon_live_data, :form_submitted], &Access.key(&1, %{})), true)
The put_in function is pretty easy to understand, it Puts a value in a nested structure via the given path
. The tricky bit is the path.
That’s where the Access.key function comes in. It essentially allows you to walk the map/struct to the nested key you need and then do the update at the final path.
socket = %{assigns: %{bill: 1, beacon_live_data: %{form_submitted: false}}}
put_in(socket, Enum.map([:assigns, :beacon_live_data, :form_submitted], &Access.key(&1, %{})), "Terry")
%{assigns: %{beacon_live_data: %{form_submitted: "Terry"}, bill: 1}}
Pretty slick!