Key :firstname not found in: %{}

I everyone i am new to elixir devlopement. My controller looks like this

defmodule MongoTestWeb.PeopleApiController do
  use MongoTestWeb, :controller

  def index(conn, _params) do
    {:ok, mn} = Mongo.start_link(url: "mongodb://localhost:27017/db-1")
    cursor = Mongo.find(mn, "people", %{})
    # people = Enum.to_list(cursor)
    people = cursor
    render(conn, "all_people.json", people: people)
    # json(conn, people)
  end
end

here is my view

defmodule MongoTestWeb.PeopleApiView do
  use MongoTestWeb, :view

  def render("all_people.json", %{people: people}) do
    %{data: render_many(people, MongoTestWeb.PeopleApiView, "people.json", as: :people)}
  end

  def render("people.json", %{people: people}) do
    %{
      firstname: people.firstname,
      lastname: people.lastname,
      contact: people.contact,
      address: people.addess
    }
  end
end

And my router

defmodule MongoTestWeb.Router do
  use MongoTestWeb, :router
  ....

  scope "/api", MongoTestWeb do
    pipe_through :api

    get("/people/all", PeopleApiController, :index)
  end

end

But rendering json gives me this following key not found error

key :firstname not found in: %{"_id" => #BSON.ObjectId<616e752f2b2a3b5cb34c4772>, "addess" => %{"city" => "Berlin", "country" => "de", "postal_code" => "12345", "street" => "Fasanenweg 5"}, "address" => %{"postal_code" => "20000"}, "contact" => %{"email" => "alexander.abendroth@campany.de", "fax" => "+49 3332929292", "mobile" => "+49 222192938383", "telephone" => "+49 111938947373"}, "firstname" => "Alexander", "lastname" => "Abendroth"}

My phoenix version v1.5.0
Elixir 1.12.0
Erlang/OTP 24 [erts-12.0]

Thanks! :smiley:

Hello and welcome,

It’s because your keys are strings, not atoms.

The syntaxic sugar people.firstname only works if firstname is an atom.

Try this…

  def render("people.json", %{people: people}) do
    %{
      firstname: people["firstname"],
      lastname: people["lastname"],
      contact: people["contact"],
      address: people["addess"]
    }
  end
3 Likes

This solved the issue. Thank you very much :pray:

2 Likes

You can also do one thing

Put this in your schema @derive {Jason.Encoder, except: [:__meta__]} and return the people in view. That way you don’t need to create an extra map.

something like this

 def render("people.json", %{people: people}) do
      people
 end

I don’t know about your requirements but this looks cleaner to me.

1 Like