Question

I'm using this code:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy
import Control.Applicative
import Debug.Trace
import Control.Monad
import qualified Data.Aeson.Types as T

main = do
  res <- liftA show (liftA decodeOriginal (Data.ByteString.Lazy.readFile "./a.json"))
  Prelude.putStrLn res

interpretResult :: Maybe String -> String
interpretResult Nothing = "Error."
interpretResult x = fromJust x

data TotalLine1 = TotalLine1 {
  timestamp :: Integer,
  value :: Integer
} deriving (Eq, Show)

data Original = Original {
  totals :: [TotalLine1]
} deriving (Eq, Show)

instance FromJSON Original where
  parseJSON (Object v) = traceStack "Original" (Original <$> (parseJSON =<< (v .: "visitors.total")))
  parseJSON _ = mzero

instance FromJSON TotalLine1 where
  parseJSON (Object v) = TotalLine1 <$>
                         v .: "timestamp" <*>
                         v .: "value"
decodeOriginal :: ByteString -> Maybe Original
decodeOriginal b = traceStack "decoding" (do
  a <- decode b :: Maybe Original
  return a)

to try and parse JSON like this:

{
visitors.total: [
{
timestamp: 1365548400,
value: 1
},
{
timestamp: 1365548700,
value: 2
},
{
timestamp: 1365549000,
value: 5
},
]
}

But main just returns Nothing every time. What have I done wrong? It seems that even parseJSON isn't being called for Original.

Was it helpful?

Solution

Your JSON file is not valid.

On the one hand, the names of the fields have to be quoted,

"timestamp"

etc. and on the other, you have a trailing comma in the list of TotalLine1s, which causes the decoding of the ByteString to a Value to fail. Quote the field names and remove the trailing comma, and it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top