stdlib icon indicating copy to clipboard operation
stdlib copied to clipboard

Dynamic cannot decode JSON dictionary

Open lucasavila00 opened this issue 1 year ago • 1 comments

In dynamic, we have "field" when we're using JSON as an "record", when we know the keys.

But when it's a mapping (random key -> value) represented as an object it cannot be decoded...

We have to_object in gleam/json https://github.com/gleam-lang/json/blob/main/src/gleam/json.gleam#L312 but not from_object

And the map (js' Map) decoder in gleam/dynamic https://github.com/gleam-lang/stdlib/blob/v0.22.3/src/gleam/dynamic.gleam#L854

But when working with json data, stuff are objects and not maps...

I ended up using:

// js
// export const to_entries = (obj) => Object.entries(obj);

// gleam

pub external fn to_entries(it: Dynamic) -> array.Array(#(a, b)) =
  "./data.mjs" "to_entries"


pub fn parse_map_from_obj(of key_type: Decoder(k), to value_type: Decoder(v)) {
  fn(it: Dynamic) {
    try pairs =
      to_entries(it)
      |> array.to_list
      |> list.try_map(fn(pair) {
        let #(k, v) = pair
        try k = key_type(k)
        try v = value_type(v)
        Ok(#(k, v))
      })
    Ok(map.from_list(pairs))
  }
}

lucasavila00 avatar Aug 12 '22 13:08 lucasavila00

Good call! Let's upgrade this function to also be able to decode JS objects

https://github.com/gleam-lang/stdlib/blob/fb560da31a313cb7e2966b131a0148a8173e9e4a/src/gleam_stdlib.mjs#L589

lpil avatar Aug 12 '22 15:08 lpil