I have the following piece of code:
data Friend = Friend
{ friend_name :: Text
, friend_inTwitter :: Bool
, friend_twitterName :: Maybe Text
}
$(deriveJSON (drop 6) ''Friend)
This piece of JSON is being posted to a handler, and I'm having a difficult time getting it. I've tried different things, but let me just put one of them here to generate suggestions:
postTestR :: Handler RepPlain
postTestR = do
value <- parseJsonBody_
return $ RepPlain $ friend_name value
That doesn't work, and I can see that the types don't match, but I'm not sure what to replace it with. I would also like to see how I could parse a list friends that gets posted as JSON.
Thanks!
Well, as it turn out, I needed to add a "toContent" call in there to convert from Text to Content. Here is a piece of code that works:
data Person = Person
{ person_firstName :: Text
, person_lastName :: Text
, person_fullName :: Text
, person_friends :: [Friend]
}
data Friend = Friend
{ friend_name :: Text
, friend_inTwitter :: Bool
, friend_twitterName :: Text
}
$(deriveJSON (drop 7) ''Person)
$(deriveJSON (drop 7) ''Friend)
postKnockoutR :: Handler RepPlain
postKnockoutR = do
value <- parseJsonBody_
let (f:fs) = person_friends value
return $ RepPlain $ toContent $ friend_name f
I'm not a Yesod expert, but if you look at the return type of parseJsonBody_
, you'll see that it's FromJSON a => GHandler sub master a
, not just plain FromJSON a => a
. This makes sense: you cannot parse the request body outside a HTTP context in which the request is accessible, and since the HTTP context is implemented as a monad, you'll have to write monadic code to deal with it.
So instead of assignment, you probably want to extract the JSON value from the Handler monad:
value <- parseJsonBody_
In your code, value
is of type GHandler sub master Friend
, which is not what you want.