Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HOWTO decode into records? #20

Open
justgage opened this issue Apr 3, 2018 · 2 comments
Open

HOWTO decode into records? #20

justgage opened this issue Apr 3, 2018 · 2 comments

Comments

@justgage
Copy link

justgage commented Apr 3, 2018

Just some nice examples in the README.md would go a long way.

Love the idea of this library by the way ❤️.

One thing I was hoping to find: How do you convert a some JSON into a record? In Elm you would use something like: http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Json-Decode#map or perhaps http://package.elm-lang.org/packages/NoRedInk/elm-decode-pipeline/latest

Example in Elm using elm-decode-pipeline

import Json.Decode exposing (int, string, float, Decoder)
import Json.Decode.Pipeline exposing (decode, required, optional, hardcoded)

-- basically a record in Elm
type alias User =
  { id : Int
  , email : Maybe String
  , name : String
  , percentExcited : Float
  }


userDecoder : Decoder User
userDecoder =
  decode User
    |> required "id" int
    |> required "email" (nullable string) -- `null` decodes to `Nothing`
    |> optional "name" string "(fallback if name is `null` or not present)"
    |> hardcoded 1.0
@johnwright
Copy link
Member

johnwright commented Apr 4, 2018

At the moment, you have to convert between tuples and records, so there's a bit of boilerplate involved. The above example would look something like this:

type user = {
  id: int,
  email: option(string),
  name: string,
  percentExcited: float
};

let userCodec = JsonCodec.(
  object4(
    field("id", int),
    field("email", nullable(string)),
    optionalNullable("name", string) |> wrap(
      fun | "" => None | name => Some(name),
      fun | Some(name) => name | None => ""
    ),
    field("percentExcited", constant(number, 1.0))
  ) |> wrap(
   fun | {id, email, name, percentExcited} => (id, email, name, percentExcited),
   fun | (id, email, name, percentExcited) => {id, email, name, percentExcited}
  )
);

I'd definitely like to look at improving this, and translating the example has already highlighted another opportunity to improve handling of default values :) Elm has kind of a head start since User is a constructor function for the record type, but maybe there's a way around that.

@strega-nil
Copy link

It seems like someone could, fairly easily, write a ppx to automate this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants