The Crystal Programming Language Forum

String to named tuple

this is newbie question, if this isn’t the right place to ask it, please re-direct me.

How do I convert a string containing valid json to a NamedTuple ?
for example:
string_output_from_api = “{first: “Alpha”, last: “Beta”}”
even though the sting contains a valid json,
I was expecting function String.to_json would remove the first char and last inverted comma characters and parse

when trying to create an object with the string, I get a runtime error
crystal-playground example:
https://play.crystal-lang.org/#/r/8adh

Calling to_json on a String will only turn it into a valid JSON string - escaping special characters like " and \n. Try comparing string_output and string_output.to_json.

In your script, string_output must be valid JSON already:

string_output = "{\"first\": \"Alpha\", \"last\": \"Beta\"}"

See how I added quotes to the object keys, and removed to_json, as that would add unwanted escape characters.

To clarify, your string_output_from_api does not contain valid JSON.

1 Like

Once you do have a string with valid JSON in it, you can use NamedTuple(first: String, last: Beta).from_json string_output. You could also create a custom struct with the expected fields like so

record FirstAndLast, first : String, last : String do
  include JSON::Serializable
end
FirstAndLast.from_json(string_output).first # => "Alpha"

thanks
I figured i was trying to convert an existing json with .to_json, which caused the issue

Blockquote
response = HTTP::Client.get("/api/me")
string_output = response.body.to_json # this caused the issue
FirstAndLast.from_json (string_output) # parsing error

instead I just needed to do

response = HTTP::Client.get("/api/me")
FirstAndLast.from_json (response.body)