kemalcr / kemal

Fast, Effective, Simple Web Framework

Home Page:https://kemalcr.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error fetching array from post params

u89012 opened this issue · comments

I can't seem to get this to work, any clues what's going on? Btw, the following was taken straight from the Guide page on kemalcr.com

post "/body_params" do |env|
  name = env.params.body["name"].as(String)
  likes = env.params.body["likes"].as(Array) <----- Error: can't cast String to Array(T) 
  "#{name} likes #{likes.join(",")}"
end

Crystal 0.35.1 (2020-06-19)

LLVM: 10.0.0
Default target: x86_64-apple-macosx

Just remove .as(Array). The return type is String and you don't need to cast it explicitly (so .as(String) can also be removed).

Sorry for the confusion but I was looking to fetch an array.

The params parser only gives you a string. So if the data is formatted in some kind of list format you need to parse it yourself. For example using String#split for a comma separated list.

@straight-shoota I think there's actually a bug with this.

With a request of:

curl --request POST \
  --url http://localhost:3000/body_params \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data name=Jim \
  --data likes=foo \
  --data likes=bar
require "kemal"

post "/body_params" do |env|
  name = env.params.body["name"].as(String)
  likes = env.params.body["likes"]

  pp env.params.body # => HTTP::Params(@raw_params={"name" => ["Jim"], "likes" => ["foo", "bar"]})

  pp likes # => "foo"
  pp typeof(likes) # => String
end

Kemal.run

It seems the data is stored correctly as an array, there just isn't a way to access it?

Thank you @Blacksmoke16 for the sample code! Yeah, that's the issue I'm talking about.

Not actually a bug. The example is just wrong I think. https://crystal-lang.org/api/HTTP/Params.html#[](name)-instance-method returns the first value. This example should probably be using .fetch_all "likes" to get the full array.

Yup! That works! Thanks a bunch @Blacksmoke16, @straight-shoota. Revised line below:

likes = env.params.body.fetch_all("likes")