0

我是 Elixir 和 Phoenix 的新手,所以这个问题可能相当简单。我的 Phoenix 应用程序是一个 API 客户端,我正在尝试创建一个结构来对我将从 REST 端点接收的数据进行建模。我基本上按照Poison GitHub 页面上的小例子来创建我的模块:

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

该模块位于lib/elixir_server/(这甚至是此类文件的最佳位置吗?)。

我的问题是当我尝试编译文件时出现此错误:

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

当我尝试运行时,iex -S mix我收到类似的错误:

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

Poison 包含在 mix.exs 的依赖项中。如何解决此错误?

4

2 回答 2

0

您的问题可能与您的项目结构或您从哪里调用命令有关。这是一个从零到凤凰的示例,说明如何获取使用Jason进行 json 编码的结构

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}
于 2020-08-28T17:27:52.283 回答
0

所以事实证明我的问题是我的模块别名。这是我elixir_server.ex之前的文件:

def repr_module do
    quote do
      use ElixirServer.CurrentlyReprModule
    end
  end

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

在我alias编辑模块之后:

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

仍然不完全确定为什么这解决了 Poison 错误,但是我们接受这些。

于 2020-08-29T20:49:49.807 回答