captDaylight
captDaylight

Reputation: 2234

Listen to Reflux actions outside of stores

I'm trying to figure out how to fit ajax calls into the flux/reflux way of doing things. From the scraps of info I've found online it seems correct to separate the API logic from the stores.

Starting there, I've created a client API that makes requests to the server. Now I want these functions them listen to my actions, then make a request, and upon success to trigger other actions that subsequently update the stores with the new data from the server.

How can go about having something similar to the reflux createStore method for my API? Or, is there some other clean way for my server calls to listen to actions?

Upvotes: 0

Views: 2201

Answers (2)

stoolio
stoolio

Reputation: 126

My Api is just a plain old javascript object (POJO) like this. It's in ES6 but you should get the idea:

import request from 'superagent';

// Other helpers functions and setup

let handle = (err) => {
  // error handling stuff
};

export default {
  create(user, cb) {
    return request
      .post(server + '/api/users/new')
      .send(user)
      .on('error', (err) => {
        handle(err);
        cb(err);
      })
      .end(cb);
  },
  login(user, cb) {
    // Post some more stuff
  }
};

Then, I call it in my Store like so:

import Reflux from 'reflux';

import UserActions from '../actions/UserActions';

import Api from '../api/UserApi';

const UserStore = Reflux.createStore({
  listenables: [UserActions],
  getInitialState() {
    // insert stuff
  },
  onCreate(user) {
    Api.create(user, (err, res) => {
      if (err) {
        console.log(err);
      } else {
        // Do something with res
        // this is for JSON, your API might be different
        let user = JSON.parse(res.text);
        this.update(user);
      }
    })
  },
  onLogin(user) {
    // login stuff
  },
  // More methods
  update(user) {
    this.currentUser = user;
    this.trigger(user);
  }
});

I don't update my store and this.trigger() until the api call returns.

A smarter idea might be to optimistically update:

// inside the todo store
onCreate(todo) {
  Api.create(todo);
  this.update([todos].concat(this.todos));
},
update(todos) {
  this.todos = todos;
  this.trigger(todos);
}

Obviously, this is one way to do it, but it's certainly not the only way.

But, the main idea is the Store uses the API.

The API is not part of the data flow of:

Action->Store->Component->Action etc.

Upvotes: 0

derflocki
derflocki

Reputation: 873

The store is the glue between your actions and the API. Just like answered in https://stackoverflow.com/a/27487312/274483

The difference in your case is that you don't perform the ajax request directly in the store, but go through your API-class, populate the store with the data returned from your API and trigger an update of the store.

Upvotes: 1

Related Questions