How to reduce a map to recursively run assign/3

I am currently refactoring some code and need to do the following:

The original author created a function that returns a fairly complex map and passes it as the third parameter to render/3. I had no idea that render/3 would take that map and create assigns for each of the keys. This still baffles me.

This function is called all over the place and tweaked and changed and copied and duplicated.

I am refactoring it to do this processing as a controller plug, and I have the whole thing working, except the final return of the conn.

The author’s functions return a map, and what I would like to return a conn with assigns for each key/value.

For a super simple example, say I end up with something like:

%{one: 1, two: 2, three: 3}

I’d like to recursively run assign/3 on each key/value and end up with

%{assigns: {one: 1, two: 2, three: 3}}

in my %Plug.conn{}

Initially, I thought about doing a reduce, but I am not sure if that’s the right approach, and I’m not sure how to code that up.

Ideas? Thanks!

Okay, I solved my own question in the process of writing out my question. debating if I should leave this in case someone else needs this i the future.

I ended up doing this:

Enum.reduce(conn, fn {key, value}, acc -> assign(acc, key, value) end )

Which runs reduce on the map, and uses the initial conn as the accumulator value.

Instead of doing an Enum.reduce you can use Phoenix.Socket.assign/2: Phoenix.Socket — Phoenix v1.5.10

It would simply be: assign(conn, my_map) which is equivalent, but more clear.


mind… blown…


1 Like