I have an ajax call sending json to a route in Yesod and I want the route to parse the json and insert it directly into the database. In my model file I have
createtime UTCTime default=now()
which is preventing parsing the json since the client isn't sending down the createtime. I tried to write my own parseJson for log entries, but I've been unable to insert a UTCTime default since getCurrentTime returns a value in the IO monad. I'd like the database to set the value, if possible.
The only thing I can think of at this point is to make a type like LogEntryWithoutTime, parse the JSON into that and convert to a LogEntry. Is there an easier way?
Edit: I show three different failures to add getCurrentTime to the JSON parse. First, the intent is to parse the createtime if available, and default to getCurrentTime on the server. This isn't right anyways, since we shouldn't rely on the client's time.
instance FromJSON Log where
parseJSON (Object o) = Log
<$> o .: "userid"
...
<*> o .:? "createtime" .!= liftIO getCurrentTime
The error is
Model.hs:58:32:
Couldn't match expected type ‘UTCTime’
with actual type ‘m0 UTCTime’
In the second argument of ‘(.!=)’, namely ‘liftIO getCurrentTime’
In the second argument of ‘(<*>)’, namely
‘o .:? "createtime" .!= liftIO getCurrentTime’
Second, I try to just get the current time.
<*> liftIO getCurrentTime
and I get the error
Model.hs:58:9:
No instance for (MonadIO
aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser)
arising from a use of ‘liftIO’
In the second argument of ‘(<*>)’, namely ‘liftIO getCurrentTime’
If I change the line to
<*> getCurrentTime
then I get
Model.hs:58:9:
Couldn't match type ‘IO’
with ‘aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser’
Expected type: aeson-0.7.0.6:Data.Aeson.Types.Internal.Parser
UTCTime
Actual type: IO UTCTime