typescript-functional-extensions icon indicating copy to clipboard operation
typescript-functional-extensions copied to clipboard

How To: Approach branching correctly

Open GregOnNet opened this issue 1 year ago • 3 comments

Hey together,

this issue is not a real request, it is a question. I approach various situations where I still need to break out of the Result-Monad. I am wondering if there is a better way to achieve this.

What situation are you talking about?

  • Create- or Update-Scenario

I try to be as specific as possible. In my project, I need to execute difference processes depending on if an Entity exists or not.

This can be situation can be abstracted to If an initial operation fails, I want to run operation A otherwise I want to run operation B.

What do you mean by breaking out of the monad.

Below you see a code-example. There I check if a resource has been linked to a document. If now I can stop right there and yielding a Result.success, otherwise I need to execute a whole other process. I cannot chain the operations by using map, mapFailure, bind since I would compensate Result.failure of independent operations that have not to do anything with each other. So compensation would be wrong. I am interested in the respected Result.failure if something goes from, and I want to log it afterwards.

In the end, I convert the ResultAsync to a promise. Introduce an if-Statement to do the control-flow.

async link(yardDelivery: YardDelivery): Promise<Result<boolean>> {
    const isAlreadyLinked = await this.yardDocumentSearchService.findOneByYardDelivery(yardDelivery).isSuccess;

    if (isAlreadyLinked) return Result.success(true);

    return await this.linkByTransportationOrderReference(yardDelivery)
      .pipe(bindFailureAsync(() => this.linkByLookingUpYardBookingReference(yardDelivery)))
      .toPromise();
  }

What is bad about the code above.

  • First, the method is async and returning a ResultAsync is not an Option any more. It is a Promise<Result<T>>
  • This makes it hard for consumers to work with the Result being nested in the Promise
  • Once started working with the Promise, all other ResultAsyncs need to be unwrapped to a Promise too, since we now must return a Promise.

I am so happy if you can provide some thoughts on this.

Thanks in advance Gregor

GregOnNet avatar Mar 23 '23 15:03 GregOnNet

https://github.com/gvergnaud/ts-pattern might provide an API that could be adopted for typescript-functional-extensions. 🤔

I think, what I am looking for is: Pattern Matching.

GregOnNet avatar Mar 24 '23 12:03 GregOnNet

I'm in the middle of changing jobs atm, so I'm gonna be a little slow on feedback. However, I'll be in the airport some over the next week and I'll use that time to sit down and think about your ideas 👍.

seangwright avatar Mar 24 '23 13:03 seangwright

Hi, no worries. I am happy to read your feedback.

GregOnNet avatar Apr 05 '23 18:04 GregOnNet