Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch object and async operations #131

Closed
FoxxMD opened this issue Feb 16, 2015 · 8 comments
Closed

Fetch object and async operations #131

FoxxMD opened this issue Feb 16, 2015 · 8 comments
Milestone

Comments

@FoxxMD
Copy link

FoxxMD commented Feb 16, 2015

How am I supposed to handle scenarios where part of my app needs a Promise but I want to use data in my stores?

Example:

During react-router's transition hook I want to determine if my user has credentials set (like in my last issue). The fetch object seems to me to be synchronous and using when only gets me the first status returned -- which is always pending.

    willTransitionTo: function (transition, params, query, callback) {
       var getCreds = AuthStore.getCredentials();
            getCreds.when({
            failed: function(){
                transition.redirect('/login');
            },
            pending: function(){
                console.log('pending');
            },
            done: function(){
                callback();
            }
        });
    }

This always returns pending. I can't use a promise like in the example from react-router's docs.

Furthermore if in a React component I only care about rendering once fetch is done I still have to write out all the handlers for when. Is this the only way to deal with fetch or am I missing something?

@jhollingworth
Copy link
Contributor

hey, this is an interesting case. Fetch results & when are designed for handling rendering state in components and the various states it's in. So right now this is what you'd have to write

var listener = AuthStore.addChangeListener(getCredentials);

getCredentials();

function getCredentials() {
    var credentials = AuthStore.getCredentials();

    if (!credentials.pending) {
        listener.dispose();
    }

    if (credentials.failed) {
        transition.redirect('/login');
    } else if (credentials.done) {
        handler();
    }
}

That said I'm wondering if there's a case for turning fetch results into promises for the times when you want state outside of stores

var credentials = AuthStore.getCredentials().toPromise();

credentals.then(function () {

}).catch(function (error) {

});

@jhollingworth
Copy link
Contributor

@FoxxMD
Copy link
Author

FoxxMD commented Feb 16, 2015

TBH fetch already feels like a pseudo-promise. Wouldn't it be easier to make store methods return promises and make fetch an explicit call? You can easily perform the same functionality with a promise that you can with fetch.

//using fetch
getData().when({
    pending: function () {
        console.log('I am pending');
    },
    failed: function () {
        console.log('I have failed');
    },
    done: function(){
        console.log('I have my data');
    }
});
if(getData().done){
    console.log(getData().result)
}
if(getData().error){
    console.log(getData().error)
}

//use an es6 promise
console.log('I am pending');
getData()
    .then(function(results){
        console.log('I have my data')})
    .catch(function(err){
        console.log('I have failed');
    });

In regards to rendering in a component, make fetch into a method fetch() than can be called on a store method so you can keep the synchronous behavior for rendering -- this way promises are default and synchronous objects are explicit (for use in rendering).

It's frustrating to have promises through the entire stack until I get to actually receiving my data from the store and then losing all advantages of asynchronous operations while still having to deal with a psuedo-promise.

@FoxxMD FoxxMD changed the title Confused by fetch object Fetch object and async operations Feb 16, 2015
@FoxxMD
Copy link
Author

FoxxMD commented Feb 16, 2015

Then again it would probably make more sense to have the promise be the method rather than changing fetch behavior to prevent breaking changes.

With promise functionality you'd be able to use marty's conveneient api features throughout the entire app instead of just renderig components 👍

@jhollingworth
Copy link
Contributor

I'd advise against dealing with asynchronicity in your component, they make your components overly complicated & difficult to test. Was main reason behind the fetch API

@FoxxMD
Copy link
Author

FoxxMD commented Feb 17, 2015

I agree with you on keeping asynchronicity out of components, I hadn't thought that through completely. Thanks for starting work on this already too! 👍 Is there anything I can do to help?

RE: 9119b47

Have you considered building the promise into fetchState()? Instead of returning a single fetchResult return fetchResult and a new Promise -- resolving or rejected the promise alongside fetchResult

@jhollingworth jhollingworth mentioned this issue Feb 19, 2015
50 tasks
@jhollingworth
Copy link
Contributor

Nothing right now thanks but looking for people to test v0.9 when its ready (week or two).

I don't want to encourage people to stick callbacks into their components so would like to keep fetch result's and promises separate for now

@jhollingworth jhollingworth removed the v0.9 label Mar 2, 2015
@jhollingworth jhollingworth modified the milestone: 0.9 Mar 2, 2015
@jhollingworth jhollingworth mentioned this issue Mar 8, 2015
4 tasks
@jhollingworth
Copy link
Contributor

This is now in the v0.9 branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants