hudsonbay
Protocol Jason.Encoder not implemented for {:ok, #Money<:USD, 20000>} of type Tuple, Jason.Encoder protocol must always be explicitly implemented
Hello, I have a very newbie question if anyone knows.
I’m using this libraries
{:ex_money, "~> 5.5.1"},
{:ex_money_sql, "~> 1.4.4"}
to deal with Money. First time I work with Money types because I was doing it using only decimals.
I configured this libraries well, I know because I can seed data with no problem using this:
Repo.insert!(%InnovationProject{
budget: Money.new(:USD, 7800),
term: 2
})
and receiving no errors at that time. And when doing GET requests the format is a Money type in the result.
So, with that out of the way, I have the following Ecto.Schema on Phoenix Framework:
schema "innovation_projects" do
field :budget, Money.Ecto.Composite.Type
field :term, :decimal
field :anual_cost, Money.Ecto.Composite.Type, virtual: true
timestamps()
end
My changeset:
def changeset(innovation_project, attrs) do
innovation_project
|> cast(attrs, [
:budget,
:term
])
|> validate_required([
:budget,
:term
])
|> calculate_anual_cost()
end
And calculate_anual_cost function looks like this:
defp calculate_anual_cost(changeset) do
budget = get_change(changeset, :budget)
term = get_change(changeset, :term)
changeset
|> put_change(:anual_cost, budget |> Money.div(term))
end
Now, I think that there’s no problem here. But my error comes when I want to show anual_cost on my views
So, my innovation_project_view.ex looks like this:
def render("innovation_project.json", %{innovation_project: innovation_project}) do
%{
budget: innovation_project.budget,
term: innovation_project.term,
anual_cost: innovation_project.anual_cost
}
end
Eyes on anual_cost: innovation_project.anual_cost because that’s the line giving me this issue:
protocol Jason.Encoder not implemented for {:ok, #Money<:USD, 20000>} of type Tuple, Jason.Encoder protocol must always be explicitly implemented. This protocol is implemented for the following type(s): Money, Cldr.LanguageTag, Ecto.Association.NotLoaded, Ecto.Schema.Metadata, BitString, List, Integer, Any, Date, Map, NaiveDateTime, Atom, Jason.Fragment, DateTime, Decimal, Time, Float
So, my view can show budget, which is a Money type but the generated virtual field anual_cost can’t be shown. How can I show my anual_cost?
One more thing:
iex> Money.div Money.new(:USD, 200), 2
{:ok, Money.new(:USD, 100)}
Thanks in advance
Marked As Solved
Nicd
The Money.div function returns a tuple of {:ok, value} or {:error, reason}. So where you are using the function, you need to pick the value out of the tuple. Jason won’t encode tuples as JSON by default, so that’s what the error comes from.
So in your changeset function you should be doing maybe something like:
with {:ok, cost} <- Money.div(budget, term) do
put_change(changeset, :anual_cost, cost)
else
{:error, reason} ->
put_error(changeset, ... something something)
end
Btw annual is written with two n’s. ![]()
Also Liked
hudsonbay
HI, thank you very much. You are so right. I told you I was a newbie ![]()
Also thanks for the typo clarification in annual
It made a lot of sense in Spanish to me ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









