Rendering a Dictionary In JSON

Hi All,

Appreciate any help on this issue, new to elixir so please feel free to point anything obvious I am doing wrong below.

I am trying to render a custom map inside a phoenix view, much like how you would represent a dictionary (I think). So I have a struct named %IndividualConversation{} and originally I was rendering a list of this struct, which I could do with the following code:

  def render("user_with_associations_and_conversations.json", %{
        user: user,
        associations: associations,
        individual_conversations: individual_conversations
      }) do
    %{
      data: %{
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        associations: render_many(associations, AssociationView, "association.json"),
        individual_conversations: render_many(individual_conversations, ConversationView, "individual_conversation.json")
      }
    }
  end

This is passing the list of the struct to the following render function:

  def render("individual_conversation.json", %{
        individual_conversation: individual_conversation
      }) do
    %{
      id: individual_conversation.id,
      recipient_user:
        render_one(individual_conversation.recipient_user, UserView, "user_from_member.json", as: :user),
      messages: individual_conversation.messages
    }

This all works fine, but I now want to change this to have the individual_conversations id to be the key of the object, so now I am passing in a list of %{^id => %IndividualConversation{}} which I need to render and I have no idea how to go about this, as I need to be able to pass the struct into the “render_one” macro.

Could I potentially be using the wrong data type?

I have probably explained this really poorly so apologies and if anyone can work out what I am on about it is again greatly appreicated.

Thanks.

1 Like

Hi All,

Just an update for any future people who run into a similar problem.

Turns out my first problem is I was trying to pass in a list of maps, when I actually just wanted a singular map to represent the dictionary.

The solution I finally worked on was to put logic in the view to enumerate through the map and call the render_one function for each of the values and create a new map with the value equal to the view result struct rather than the actual struct.

This looked like as follows

  def render("user_with_associations_and_conversations.json", %{
        user: user,
        associations: associations,
        individual_conversations: individual_conversations
      }) do
    individual_conversations =
      Enum.into(
        Enum.map(individual_conversations, fn {key, value} ->
          {key, render_one(value, ConversationView, "individual_conversation.json")}
        end),
        %{}
      )

    %{
      data: %{
        id: user.id,
        email: user.email,
        firstName: user.first_name,
        lastName: user.last_name,
        associations: render_many(associations, AssociationView, "association.json"),
        individual_conversations:
          individual_conversations
      }
    }
  end
3 Likes