goatslacker / alt

Isomorphic flux implementation
http://alt.js.org/
3.45k stars 323 forks source link

DataSource issue: Cannot dispatch in the middle of a dispatch #556

Closed maxs15 closed 8 years ago

maxs15 commented 8 years ago

Hi,

I'm having some trouble using the DataSource, for some reason I'm stuck with a: Uncaught Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. When called my DataSource method post.. Am I missing something ?

Here is my code:

Store and source:

var alt                                 = require('../alt');
var appSubmitActions        = require('../actions/appsubmit');

var source = {
    post: {
        remote(state) {
            return util.post('app', state.data);
        },
        loading: appSubmitActions.loading,
        success: appSubmitActions.results,
        error: appSubmitActions.error
    }
};

class AppSubmitStore {

    constructor() {
        this.bindActions(appSubmitActions);
        this.registerAsync(source);
        /* STATES */
        this.data = null;
    }

    onCreate(data) {
        this.data = data;
        if (!this.getInstance().isLoading()) {
              this.getInstance().post(); // Having the exception here
        }
    }

}

module.exports = alt.createStore(AppSubmitStore, 'appsubmit');

Action:

var alt  = require('../alt');

class AppSubmitActions {

    constructor() {
        this.generateActions('create', 'loading', 'results', 'error');
    }

}

module.exports = alt.createActions(AppSubmitActions);

Thanks for the help :)

goatslacker commented 8 years ago

That's because the post fires a loading action immediately.

There are a few things you can do here:

Try firing post from wherever the user interaction happens.

maxs15 commented 8 years ago

Thanks Josh ! Problem solved :+1:

thebitguru commented 8 years ago

I realize that this issue is closed, but I was still confused on the suggestion so I am hoping that someone can clarify. In this case the suggestion is to call post from the view? So, something like AppSubmitStore.post()?

Since this function is defined on the store, wouldn't this break the flux pattern which recommends that the view shouldn't touch the Store directly, and instead only call actions?

goatslacker commented 8 years ago

The flux pattern is don't mutate store state from the view directly but rather initiate everything through actions. Calling this store public method initiates an action so that's ok.

If that bothers you though you could abstract that source method out of the store and put it in a utility function somewhere else.

thebitguru commented 8 years ago

Thanks, @goatslacker. I did notice that this was an action, but it was weird that the action is defined on the store.

thebitguru commented 8 years ago

One other question, there is no defer() method on the functions so I can't call a these as deferred actions. Am I doing something wrong here? Is there another way to do this?

magrinj commented 8 years ago

I everyone, I think the documentation need to be edited: here There is nothing that specify the loading action need to be defer or something else.