RafalKostecki

RafalKostecki

Ecto.CastError, expected params to be a :map

Hi there!
I am the new one in Elixir. Lately, I constantly facing the Ecto.CastError, expected params to be a :map.

I created a GraphQL API suing Phoenix and Absinthe. My goal is to convert one struct into another and insert it into another table in database. I mean, I have X and i wanna modify them to become an Y data type and insert them to Y table in DB.

I wrote code below (maybe there is an easier/better way to achieve my goal)

requested_chars.ex

import Ecto.Query, warn: false
  alias AngotiaCatalogsApi.Repo

  alias AngotiaCatalogsApi.RequestedChars.Char, as: RChar
  alias AngotiaCatalogsApi.Chars.Char

defp push_to_prod(char) do
    req_char = elem(char, 1)
    prod_char = req_char
      |> Map.delete(:__meta__)
      |> Map.delete(:__struct__)
      |> Map.delete(:author)
      |> Map.delete(:id)

    prod_char_struct = struct(Char, prod_char)

    %Char{}
      |> Char.changeset(prod_char_struct)
      |> Repo.insert()
  end

Where Char is another db table struct.

char.ex

defmodule AngotiaCatalogsApi.Chars.Char do
  use Ecto.Schema
  import Ecto.Changeset
  alias AngotiaCatalogsApi.Chars.Statistics
  alias AngotiaCatalogsApi.Chars.Settings
  alias AngotiaCatalogsApi.Chars.Monolog
  alias AngotiaCatalogsApi.Chars.Dialog


  schema "chars" do
    field :name, :string
    field :_id, :string
    field :field_diameter, :integer
    field :type, :string, default: "static"
    field :choosed, :string
    field :has_visible_level, :boolean, default: true
    field :char_pic, :string
    field :mob_range, :string
    field :is_agressive_mob, :boolean
    embeds_one :statistics, Statistics, on_replace: :update
    embeds_one :settings, Settings, on_replace: :update
    embeds_many :monologs, Monolog, on_replace: :delete
    embeds_many :dialogs, Dialog, on_replace: :delete

    timestamps()
  end

  def changeset(char, attrs) do
    char
    |> cast(attrs, [:name, :_id, :field_diameter, :type, :choosed, :has_visible_level, :char_pic, :mob_range, :is_agressive_mob])
    |> validate_required([:name, :_id, :field_diameter, :choosed, :has_visible_level, :char_pic])
    |> cast_embed(:statistics, with: &Statistics.changeset/2)
    |> cast_embed(:settings, with: &Settings.changeset/2)
    |> cast_embed(:monologs, with: &Monolog.changeset/2)
    |> cast_embed(:dialogs, with: &Dialog.changeset/2)
  end  
end

Full stack trace:

"# Ecto.CastError at POST /graphiql\n\nException:\n\n    ** (Ecto.CastError) expected params to be a :map, got: `%AngotiaCatalogsApi.Chars.Char{__meta__: #Ecto.Schema.Metadata<:built, \"chars\">, _id: \"160d1867-605f-4949-a6f0-ce9e2de068d6\", char_pic: \"afwa\", choosed: \"NPC\", dialogs: [], field_diameter: 0, has_visible_level: true, id: nil, inserted_at: ~N[2021-01-26 17:00:40], is_agressive_mob: false, mob_range: nil, monologs: [], name: \"test1\", settings: %AngotiaCatalogsApi.Chars.Settings{id: \"a93830bd-912b-4e1b-9a20-1f9ba9fae56a\", resp_time: %AngotiaCatalogsApi.Chars.Settings.RespTime{id: \"b5b6507c-b23e-49a2-af33-c4174284c89c\", max: 130, min: 60}, time_of_occurance: %AngotiaCatalogsApi.Chars.Settings.TimeOfOccurance{id: \"2a9674f4-d804-4e4c-b8cd-d85caf9bedd9\", max: 24, min: 0}}, statistics: %AngotiaCatalogsApi.Chars.Statistics{attack: 1, attack_range: 1, attack_speed: 100, defence: 1, dexterity: 1, health: 1000, id: \"142460ee-bf0c-4654-8ea6-dbbf1f9f4200\", inteligence: 1, jink: 1, level: 1, speed: 1, strength: 1}, type: \"STATIC\", updated_at: ~N[2021-01-26 17:00:40]}`\n        (ecto 3.4.5) lib/ecto/changeset.ex:457: Ecto.Changeset.cast/4\n        (angotia_catalogs_api 1.0.0) lib/angotia_catalogs_api/chars/char.ex:30: AngotiaCatalogsApi.Chars.Char.changeset/2\n        (angotia_catalogs_api 1.0.0) lib/angotia_catalogs_api/requested_chars/requested_chars.ex:38: AngotiaCatalogsApi.RequestedChars.push_to_prod/1\n        (absinthe 1.5.1) lib/absinthe/resolution.ex:209: Absinthe.Resolution.call/2\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:230: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:185: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/3\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:170: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:88: Absinthe.Phase.Document.Execution.Resolution.walk_result/5\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:67: Absinthe.Phase.Document.Execution.Resolution.perform_resolution/3\n        (absinthe 1.5.1) lib/absinthe/phase/document/execution/resolution.ex:24: Absinthe.Phase.Document.Execution.Resolution.resolve_current/3\n        (absinthe 1.5.1) lib/absinthe/pipeline.ex:368: Absinthe.Pipeline.run_phase/3\n        (absinthe_plug 1.5.0) lib/absinthe/plug.ex:445: Absinthe.Plug.run_query/4\n        (absinthe_plug 1.5.0) lib/absinthe/plug.ex:258: Absinthe.Plug.call/2\n        (phoenix 1.5.7) lib/phoenix/router/route.ex:41: Phoenix.Router.Route.call/2\n        (phoenix 1.5.7) lib/phoenix/router.ex:352: Phoenix.Router.__call__/2\n        (angotia_catalogs_api 1.0.0) lib/angotia_catalogs_api_web/endpoint.ex:1: AngotiaCatalogsApiWeb.Endpoint.plug_builder_call/2\n        (angotia_catalogs_api 1.0.0) lib/plug/debugger.ex:132: AngotiaCatalogsApiWeb.Endpoint.\"call (overridable 3)\"/2\n        (angotia_catalogs_api 1.0.0) lib/angotia_catalogs_api_web/endpoint.ex:1: AngotiaCatalogsApiWeb.Endpoint.call/2\n        (phoenix 1.5.7) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4\n        (cowboy 2.8.0) /home/kostek/Documents/Programming/angotia-catalogs/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2\n    \n\n## Connection details\n\n### Params\n\n    %{\"query\" => \"mutation {\\n  acceptRequestedChar(id: 68) {\\n    id\\n  }\\n}\", \"variables\" => %{}}\n\n### Request info\n\n  * URI: http://localhost:4000/graphiql\n  * Query string: \n\n### Headers\n  \n  * accept: application/json\n  * accept-encoding: gzip, deflate\n  * accept-language: en-US,en;q=0.5\n  * cache-control: no-cache\n  * connection: keep-alive\n  * content-length: 86\n  * content-type: application/json\n  * cookie: next-i18next=en\n  * host: localhost:4000\n  * origin: http://localhost:4000\n  * pragma: no-cache\n  * referer: http://localhost:4000/graphiql?variables=%7B%7D&query=mutation%20%7B%0A%20%20acceptRequestedChar(id%3A%2068)%20%7B%0A%20%20%20%20id%0A%20%20%7D%0A%7D\n  * user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0\n\n### Session\n\n    %{}\n"

I see that my struct properly refer to Ecto “chars” schema. So whats wrong?

Marked As Solved

RafalKostecki

RafalKostecki

Okey, I found out whats goin on.

Nicd was right about Map type. My error was due to nested Structs inside Map. So I needed to convert nested Struct into nested Map and everything works fine!

About conversion: Convert a nested struct into a nested map

Also Liked

Nicd

Nicd

The input parameter attrs in your code to Ecto.Changeset.cast/4 should be a map, not a struct. The point of the changeset functionality is to build a set of changes to a struct (the char struct that you also input). Providing the changes as a struct doesn’t really make sense then.

So, instead of passing a struct to the changeset function, just pass a map.

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement