Returning promise from reflux store

1.4k views Asked by At

I'm working on my first react/reflux app so I may be approaching this problem in completely the wrong way. I'm trying to return a promise from a reflux store's action handler. This is the minimum code that represents how I'm trying to do this. If I display this in the browser, I get an error saying that the promise is never caught, because the result of the onLogin function is not passed back when the action is initiated. What is the best way to do this?

var Reflux = require('reflux');
var React = require('react/addons')

const Action = Reflux.createAction();
const Store = Reflux.createStore({
    init: function() {
        this.listenTo(Action, this.onAction);
    },

    onAction: function(username, password) {
        var p = new Promise((resolve, reject) => {
            reject('Bad password');
        });

        return p;
    }
});

var LoginForm = React.createClass({
    mixins: [Reflux.connect(Store, 'store')],
    login: function() {
        Action('nate', 'password1').catch(function(e) {
            console.log(e); // This line is never executed
        });
    },
    render: function() {
        return (
            <a onClick={this.login} href="#">login</a>
        )
    }
});

React.render(<LoginForm />, document.body);
1

There are 1 answers

0
Hannes Johansson On

Several things seem a bit confused here.

  1. Reflux.connect(Store, 'store') is a shorthand for listening to the provided store, and automatically set the "store" property of your component state to whatever is passed in your store's this.trigger() call. However, your store never calls this.trigger so "store" in your component's state will never be updated. Returning a value from your store's action handlers doesn't trigger an update.

  2. Stores should listen to actions to update their internal state, and typically then broadcast this state update by calling this.trigger. No component is going to get your returned promise from the store's onAction unless it explicitly calls Store.onAction (and then it doesn't matter if the actual action was invoked or not).

  3. Async work should typically happen in the action's preEmit hook, not in the store. You should then also declare the action as async in createAction by setting the asyncResult option to true to automatically create "completed" and "failed" child actions. Check out the Reflux documentation here to learn about async events. Async actions automatically return promises, whose resolve and reject are called when the "completed" and "failed" sub-actions are called respectively. This is a bit opinionated, but that is definitely what I perceive is the intended Reflux way.