0

I am new to Elixir and Phoenix so this problem is probably fairly trivial. My Phoenix application is an API client and I am trying to create a struct to model the data I will receive from the REST endpoint. I basically followed the small example on the Poison GitHub page to create my module:

defmodule ElixirServer.CurrentlyReprModule do
  @derive [Poison.Encoder]

  defstruct [:id, :time, :summary, :icon, :nearestStormDistance,
    :nearestStormBearing, :precipIntensity, :precipProbability, :temperature,
    :apparentTemperature, :dewPoint, :humidity, :pressure, :windSpeed, :windGust,
    :windBearing, :cloudCover, :uvIndex, :visibility, :ozone]
end

The module is located under lib/elixir_server/ (is this even the best location for this type of file?).

My problem is when I try to compile the file I get this error:

(CompileError) lib/elixir_server/currently_repr_module.ex:2: module Poison.Encoder is not loaded and could not be found

When I try to run iex -S mix I get a similar error:

(UndefinedFunctionError) function Poison.Encoder.__using__/1 is undefined or private

Poison is included in the dependencies in mix.exs. How do I resolve this error?

Walker Sorlie
  • 53
  • 1
  • 1
  • 7

2 Answers2

0

Your issue might be with the structure of your project or where you are invoking commands from. Here is a zero to phoenix example of how to get a struct that is json encoded using Jason

mix phx.new poison_demo --no-webpack --no-ecto
Fetch and install dependencies? [Yn] y
cd poison_demo

lib/poison_demo_web/router.ex

defmodule PoisonDemoWeb.Router do
  use PoisonDemoWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/api", PoisonDemoWeb do
    pipe_through :api
    get "/repr", ReprController, :show
  end
end

lib/poison_demo_web/controllers/repr_controller.ex

defmodule PoisonDemoWeb.ReprController do
  use PoisonDemoWeb, :controller

  def show(conn, _params) do
    json(conn, %CurrentlyReprModule{})
  end
end

lib/repr/repr.ex

defmodule CurrentlyReprModule do
  @moduledoc false
  
  @derive Jason.Encoder
  defstruct [:id, :time, :summary, :icon, :nearestStormDistance,
    :nearestStormBearing, :precipIntensity, :precipProbability, :temperature,
    :apparentTemperature, :dewPoint, :humidity, :pressure, :windSpeed, :windGust,
    :windBearing, :cloudCover, :uvIndex, :visibility, :ozone]
end
iex -S mix phx.server
curl localhost:4000/api/repr

{"apparentTemperature":null,"cloudCover":null,"dewPoint":null,"humidity":null,"icon":null,"id":null,"nearestStormBearing":null,"nearestStormDistance":null,"ozone":null,"precipIntensity":null,"precipProbability":null,"pressure":null,"summary":null,"temperature":null,"time":null,"uvIndex":null,"visibility":null,"windBearing":null,"windGust":null,"windSpeed":null}
sdc
  • 2,603
  • 1
  • 27
  • 40
0

So it turns out my problem was with aliasing my module. This was my elixir_server.ex file before:

def repr_module do
    quote do
      use ElixirServer.CurrentlyReprModule
    end
  end

  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end

and after I aliased the module:

def repr_module do
    quote do
      alias ElixirServer.CurrentlyReprModule, as: CurrentlyReprModule
    end
  end

  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end

Still not exactly sure why that solved the Poison error, but hey we take those.

Walker Sorlie
  • 53
  • 1
  • 1
  • 7