joanllenas / ts.data.json

1.7kB JSON decoding library for Typescript
BSD 3-Clause "New" or "Revised" License
205 stars 16 forks source link

feat: Add new mapError transformer #26

Closed knuterikl closed 4 years ago

knuterikl commented 4 years ago

mapError

Transforms an error into a value.

const decoder = JsonDecoder.number.mapError((error) => {
    console.warn(error)
    return 0
})

decoder.decode(10) // Ok<10>
decoder.decode("fail") // Ok<0> and "Warning: "fail" is not a number" in console
joanllenas commented 4 years ago

Hi @knutbekk , nice feature. I'll review / merge / release during the weekend. Thanks for your contribution!

joanllenas commented 4 years ago

Hi @knutbekk , I want to make sure I understand the purpose of this function. Why is it useful that mapError can return a different type than the decoder type? i.e. <a | b>? Why not just <a> (the original decoder's expected return type).

knuterikl commented 4 years ago

Hi @knutbekk , I want to make sure I understand the purpose of this function. Why is it useful that mapError can return a different type than the decoder type? i.e. <a | b>? Why not just <a> (the original decoder's expected return type).

So that you can "detect" that the decoder has failed. In usage with an object decoder inside an array decoder one might want to map to null instead of the a object type, to filter out the failed values instead of using fallback to a default value. As well as having access to the error of the failing decoder:


const tagsDecoder = JsonDecoder.object({
    id: JsonDecoder.string,
    title: JsonDecoder.string,
)}.mapError((error) => {
    // Log the error to remote logger so we can investigate whats wrong
    remoteLogger.log(error)

   return null
})

const userDecoder = JsonDecoder.object({
    tags: JsonDecoder.array(tagsDecoder, "TagsDecoder").map(arr => arr.filter(notNull))
}, "UserDecoder")
joanllenas commented 4 years ago

Thanks again for your contribution!