Hyrum Carlile
Hyrum Carlile

Reputation: 117

Create Granite model from JSON params

What I would like to have happen: Someone can make a post request to users/new with parameters, and I would like to create a User object from the JSON parameters.

In the readme, it gives this example:

foo = Foo.from_json(%({"name": "Granite1"}))

But when I try to do this I get this compile-time error:

in /usr/local/Cellar/crystal/0.26.1/src/json/pull_parser.cr:13: no 
overload matches 'JSON::Lexer.new' with type Hash(String, Array(JSON::Any) | Bool | Float64 | Hash(String, JSON::Any) | Int64 | String | Nil)

Overloads are:
- JSON::Lexer.new(string : String)
- JSON::Lexer.new(io : IO)
- JSON::Lexer.new()

@lexer = Lexer.new input
               ^~~

Here is what env.params.json looks like when logged to the console:

{"name" => "test",
 "username" => "tester",
 "email" => "test",
 "password" => "test"}

Any help would be much appreciated.

Upvotes: 0

Views: 140

Answers (1)

pixatlazaki
pixatlazaki

Reputation: 561

The compiler is steering you in the right direction here. It looks like you're passing in a variable that, at compile-time, has the type Hash(String, V) where V is one of the types

  • Array(JSON::Any)
  • Bool
  • Float64
  • Hash(String, JSON::Any)
  • Int64
  • String
  • Nil

What it's expecting is a String (or an IO object, which is similar to a String) of JSON. That's what you have in the example. %(foo) is another way to create the String "foo" (See "Percent string literals" in the guide for more info). They're using it here because it allows you to avoid escaping the double quotes used in the JSON.

Based on the compile-time type that Crystal has given your parameter, my guess is that it's already been converted from JSON into a Crystal Hash. Double-check that you're not parsing it twice.

Without seeing the source, there's not much more information I can provide, but I hope that helps.

Upvotes: 1

Related Questions