Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upRuntime error when decoding Json #624
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
May 26, 2016
Contributor
The problem is the recursive dependency of tweetDetails on itself. This is currently not supported, the issue that needs to be fixed in order to support it is this: elm/compiler#873. It's well known, so I'm closing this issue here.
To work around the issue currently, you should use lazy and force from http://package.elm-lang.org/packages/elm-lang/lazy. For more details, check out some of the issues mentioning "JSON" or "decode" listed over at elm/compiler#873.
|
The problem is the recursive dependency of To work around the issue currently, you should use |
jvoigtlaender
closed this
May 26, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
May 26, 2016
Contributor
Something like this should work:
decodeTweets : Json.Decoder (List TweetModel)
decodeTweets =
force tweetDetails |> Json.list
tweetDetails : Lazy (Json.Decoder TweetModel)
tweetDetails = lazy <| \_ ->
Json.object3 TweetModel
("id" := Json.float)
("text" := Json.string)
(Json.maybe ("retweeted_status" := force tweetDetails |> Json.map RetweetedStatus))|
Something like this should work: decodeTweets : Json.Decoder (List TweetModel)
decodeTweets =
force tweetDetails |> Json.list
tweetDetails : Lazy (Json.Decoder TweetModel)
tweetDetails = lazy <| \_ ->
Json.object3 TweetModel
("id" := Json.float)
("text" := Json.string)
(Json.maybe ("retweeted_status" := force tweetDetails |> Json.map RetweetedStatus)) |
jvoigtlaender
referenced this issue
May 26, 2016
Closed
Support for package elm-lang/lazy at /try #578
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
patrik-piskay
commented
May 26, 2016
|
Thanks @jvoigtlaender |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
patrik-piskay
May 26, 2016
I used this approach and now I am getting Maximum call stack size exceeded error. I will probably fix this by refactoring the code and use another decoder for retweet as there should not be any retweeted_status inside retweeted_status. I just wanted to reuse one decoder recursively as the rest of the structure is the same.
But what I am curious about, I got to this code by following this hint about recursive types/type aliases and if I would be expecting a response Json of shape used in example there (messages that can have response messages and those can have response messages and so on), what would be the working approach there? I would need to use some kind of recursive decoder there like I was doing with the tweets and lazy approach just produces a different runtime error.
Thanks for pointing me to the right direction, still new to Elm :)
patrik-piskay
commented
May 26, 2016
•
|
I used this approach and now I am getting But what I am curious about, I got to this code by following this hint about recursive types/type aliases and if I would be expecting a response Json of shape used in example there (messages that can have response messages and those can have response messages and so on), what would be the working approach there? I would need to use some kind of recursive decoder there like I was doing with the tweets and lazy approach just produces a different runtime error. Thanks for pointing me to the right direction, still new to Elm :) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
May 26, 2016
Contributor
... what would be the working approach there? I would need to use some kind of recursive decoder there like I was doing with the tweets and lazy approach just produces a different runtime error.
The working approach should be the one using lazy and force. Other people, in some of the GitHub issues I mentioned earlier, the ones listed at elm/compiler#873 that are about JSON decoding, have successfully used that approach to deal with decoding recursive structures, such as decoding JSON data that corresponds to types like this:
type Tree = Leaf Int | Node Tree TreeSo this approach is not unworking per se. Why it does not work in your specific case is difficult to diagnose without having an actual http://sscce.org/, including a call with a concrete JSON input that you expect to be able to decode but get the runtime error on.
The working approach should be the one using type Tree = Leaf Int | Node Tree TreeSo this approach is not unworking per se. Why it does not work in your specific case is difficult to diagnose without having an actual http://sscce.org/, including a call with a concrete JSON input that you expect to be able to decode but get the runtime error on. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
May 27, 2016
Contributor
Coming back to this since it was pointed out in elm/elm-lang.org#578 that lazy from elm-lang/lazy is overkill. So the following should work at http://elm-lang.org/try, and handle your case:
decodeTweets : Json.Decoder (List TweetModel)
decodeTweets =
lazy (\_ -> tweetDetails) |> Json.list
tweetDetails : Json.Decoder TweetModel
tweetDetails =
Json.object3 TweetModel
("id" := Json.float)
("text" := Json.string)
(Json.maybe ("retweeted_status" := lazy (\_ -> tweetDetails) |> Json.map RetweetedStatus))
lazy : (() -> Json.Decoder a) -> Json.Decoder a
lazy thunk =
Json.customDecoder Json.value
(\js -> Json.decodeValue (thunk ()) js)It's possible the lazy-call in decodeTweets is even superfluous.
|
Coming back to this since it was pointed out in elm/elm-lang.org#578 that decodeTweets : Json.Decoder (List TweetModel)
decodeTweets =
lazy (\_ -> tweetDetails) |> Json.list
tweetDetails : Json.Decoder TweetModel
tweetDetails =
Json.object3 TweetModel
("id" := Json.float)
("text" := Json.string)
(Json.maybe ("retweeted_status" := lazy (\_ -> tweetDetails) |> Json.map RetweetedStatus))
lazy : (() -> Json.Decoder a) -> Json.Decoder a
lazy thunk =
Json.customDecoder Json.value
(\js -> Json.decodeValue (thunk ()) js)It's possible the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
patrik-piskay
commented
May 27, 2016
|
Thanks |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
carltongibson
Jul 27, 2016
I found this via the same path as @patrik-piskay — via working through recursive type aliases advice and then hitting the runtime error.
For me using lazy from the elm-community/json-extras package was super simple.
(I leave the note for the future.
carltongibson
commented
Jul 27, 2016
|
I found this via the same path as @patrik-piskay — via working through recursive type aliases advice and then hitting the runtime error. For me using (I leave the note for the future. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jvoigtlaender
Jul 28, 2016
Contributor
Yes, lazy from that package is like the lazy from my comment above. That package is not available at http://elm-lang.org/try, though, so when trying out stuff there (as above) an explicit definition of lazy is needed.
|
Yes, |
patrik-piskay commentedMay 26, 2016
•
edited
Edited 1 time
-
patrik-piskay
edited May 26, 2016 (most recent)
I am getting
Uncaught TypeError: Cannot read property 'tag' of undefined(https://github.com/elm-lang/core/blob/32b8fd9b3f2f1f6ef2c1d3a7914427e7a646770c/src/Native/Json.js#L313) when decoding Json.Repo with minimum code required to replicate the issue with Json response hardcoded here
Main parts:
The issue seems to be related to the
RetweetedStatustype and and its usage in decoder. Without it, everything works fine.In twitter response, in each tweet record there may or may not be a
retweeted_statuskey, hence theJson.Decode.maybe