-
|
Hello! I've just started learning functional programming in TypeScript and recently watched Artem's talk about the Either monad. However, this repository lacks examples with asynchronous code. Could you provide an example using the following functions: import { Either, left, right } from '@sweet-monads/either';
import sharp from 'sharp';
export async function _convertImage(
rawImage: Express.Multer.File,
): Promise<Either<Error, sharp.Sharp>> {
try {
const image = sharp(rawImage.buffer);
const metadata = await image.metadata();
if (metadata.format === 'webp') {
return right(image);
}
const webImage = image.webp();
return right(webImage);
} catch (error) {
console.log(error);
return left(new Error('Error converting image'));
}
}
export async function _resizeImage(
originImage: sharp.Sharp,
size: number,
): Promise<Either<Error, sharp.Sharp>> {
try {
const metadata = await originImage.metadata();
if (!metadata || !metadata.width || !metadata.height) {
return left(new Error('Incorrect size'));
}
let width: number, height: number;
if (metadata.width >= metadata.height) {
width = size;
height = Math.round(metadata.height * (size / metadata.width));
} else {
height = size;
width = Math.round(metadata.width * (size / metadata.height));
}
return right(originImage.resize({ width, height, fit: 'contain' }));
} catch (error) {
console.log(error);
return left(new Error('Error resizing image'));
}
}How can I properly and elegantly handle these functions in a chain without using type checks like: Thank you in advance 😉 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
|
@JSMonk Is this still a live project? |
Beta Was this translation helpful? Give feedback.
-
|
@Wheatgrh Yes, sure. Sorry for the late reply. import { chain } from '@sweet-monads/either';
import type { Either } from '@sweet-monads/either';
// First variant with the static `chain` function
function resizeImageFile(maybeImage: Express.Multer.File): Promise<Either<Error, sharp.Sharp>> {
return _convertImage(maybeImage)
.then(chain(image => _resizeImage(image, expectedSize)))
}
// Second variant with the `chainAsync` function
async function resizeImageFile(maybeImage: Express.Multer.File): Promise<Either<Error, sharp.Sharp>> {
const eitherImage = await _convertImage(maybeImage) // Either<Error, sharp.Sharp>
const eitherResizedImage = await eitherImage.chainAsync(image => _resizeImage(image, expectedSize));
return eitherResizedImage;
} |
Beta Was this translation helpful? Give feedback.
@Wheatgrh Yes, sure. Sorry for the late reply.
The keys to the async operations are the static chain function and instance asyncChain function, so I see that the usage of the described functions would look like this: