Coder Social home page Coder Social logo

Comments (15)

sutarmin avatar sutarmin commented on June 2, 2024 1

I would keep toOption because there are cases.
Consider we have UI component which accepts value wrapped into Option and just renders a placeholder if the value is none. Now we want to render data from API using this component. Without toOption we would have:

value.fold(none, none, () => none, some); // ugly

So it does make sense to me.
The same for toEither, there could be cases.

I believe the question here is "Do we want to have close integration with other fp-ts ADTs from inside of RemoteData?". My opinion is "yes" because RemoteData is implemented over fp-ts and if you are using remote-data-ts you are likely using fp-ts by itself.

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024 1

@scotttrinh Well the main goal of this project is to be 100% typesafe, not to force some design patterns. It should be up to developer how to use RemoteData so I think it's ok to provide such API. Would you like to oper PR?

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

@scotttrinh How would you represent RemoteInitial and RemotePending?

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

Excellent question. 🤔

Maybe the signature would require a function for each of those two cases?

toEither: <L, A>(initial: () => Left<L> | Right<A>, pending: () => Left<L> | Right<A>);

Totally contrived example:

data.toEither<string, Resource[]>(
  () => left('No data loaded'),
  () => right([])
);

Perhaps not all that helpful? Easy enough to make a separate function for each case.

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

Could you please describe your usecase? Do you really need to convert RemoteData context to less powerful Either? Even existing toOption/toNullable seem to be a bad practice because they allow you to drop parts of the context.

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

I use toOption all of the time when I want to do the same thing to initial/pending/failure and another to success. My thought around toEither is to have something in between that can account for failure separately.

Like I said, it's easy enough to create this as a function, so if it's not in scope for this library, that's fine. Just figured since toOption already existed, a similar toEither might be helpful.

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

I use toOption all of the time when I want to do the same thing to initial/pending/failure and another to success.

Could you provide an example? Seems like either we don't use toOption in our codebase at all or such places are considered deprecated and invalid because of unnecessary context destruction.

The problem is that toOption was introduced to replicate Either API from fp-ts and is now considered bad practice (in our codebase). Even more I believe it should be deprecated.

/cc @mankdev @sutarmin

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

@sutarmin This is incorrect because you should use renderRemoteData to render RemoteData instead of destroying the context.

This is not the question of integration because Either.toOption is absolutely valid as the value of Either (or error) is always resolved while RemoteData context adds an unresolved state to the value. IMO such case should not be treated as None because RemoteInitial and RemotePending describe unresolved states.

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

To be fair, I'm using a fork of this library with an additional state, RemoteRefresh, that kind of acts like a RemotePending but with (potentially stale) data. I'm considering adding the toEither method in my fork, and want to offer it "back upstream".

My current use-case involves setting data to pending | refresh depending on whether there is existing data, which I do constantly.

As I readily admitted before, either of these is pretty easily accomplished as a function instead of an instance method that just calls #fold for the consumer:

toOption: <L, A>(data: RemoteData<L, A>) => Option<A>
toEither: <L, A>(data: RemoteData<L, A>, initial: () => Left<L> | Right<A>, pending: () => Left<L> | Right<A>);

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

IMO such case should not be treated as None because RemoteInitial and RemotePending describe unresolved states.

I would say that the idea of mapping between domains and loosing structure is a pretty common practice, so I don't personally have a problem with that. Const, for instance, is an example of something useful that maps everything into a single value. Not a big deal if it's not an instance method since the ergonomics of using a function is just as good, and this doesn't need access to some hidden internal state.

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

I'd be happy to open a PR. Do you think the fold-like behavior for mapping the initial and pending states makes sense? You could also just have a single function or value that represents both states.

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

@scotttrinh I think if we distinguish RemoteInitial and RemotePending then we should also processs them separately. A method signature could be:

toEither: RemoteData<L, A> ~> (initial: Lazy<L>, pending: Lazy<L>) => Either<L, A>

from remote-data-ts.

raveclassic avatar raveclassic commented on June 2, 2024

Or even:

toEither: RemoteData<L, A> ~> (initial: L, pending: L) => Either<L, A>
toEitherL: RemoteData<L, A> ~> (initial: Lazy<L>, pending: Lazy<L>) => Either<L, A>

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

@raveclassic

Oh, I like having toEither and toEitherL! Do we think it's necessary that initial and pending have type L or could it be L | A?

from remote-data-ts.

scotttrinh avatar scotttrinh commented on June 2, 2024

Do we think it's necessary that initial and pending have type L or could it be L | A?

Nevermind! The extra runtime overhead and complexity isn't worth the extra flexibility, and there are often cases where L and A are the same type, so initial and pending both mapping to Left<L>.

from remote-data-ts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.