Input to the mapping function
The mapping function returns a decoder for this type
Maybe our HTTP API of choice wraps the data in an object that contains information about the success of the operation. Depending on that value we want to handle the data differently.
const UserDecoder = Decode.object({
id: Decode.field('id', Decode.integer),
name: Decode.field('name', Decode.string),
});
const response_decoder = Decode.andThen(
success => {
if (success) {
return Decode.field('data', UserDecoder);
} else {
return Decode.andThen(
error => Decode.fail('Got an error response: ' + error),
Decode.field('error', Decode.string),
);
}
},
Decode.field('success', Decode.bool),
);
// Works
decode(response_decoder, {
success: true,
data: {
id: 1,
name: 'Kobe Bryant',
},
});
// Fails
decode(response_decoder, {
success: false,
error: 'Could not find user!',
});
This is nice and all, but it only works for the UserDecoder. However, making it generic is rather simple. You just wrap the Decoder in a function and accept the data decoder as an argument:
function responseDecoder<T>(child: Decoder<T>): Decoder<T> {
return Decode.andThen(success => {
if (success) {
return Decode.field('data', child);
} else {
// etc.
}
}, Decode.field('success', Decode.boolean');
}
Generated using TypeDoc
Similar to Decode.map, but you return a decoder instead of a value. This allows you to decide how to continue decoding depending on the result.