A flux implementation without the boilerplate
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
.vscode
src
test
.babelrc
.editorconfig
.gitignore
.npmignore
.travis.yml
Alt.js
AltContainer.js
CONTRIBUTING.md
LICENSE
README.md
Store.js
package.json

README.md

alt-ng

Build Status Coverage Status NPM Downloads

alt-ng is a Flux implementation that removes all the boilerplate traditionally associated to managing data. alt-ng is based on JavaScript classes, does not use switch statements and supports Promises out-of-the-box. Check out the tutorial, or jump straight into the documentation.

Features of alt-ng

  • Promises are first class citizens
  • Lightweight: A lot of code has been removed from the original alt implementation to make it even more lightweight
  • No constants or switch statements: Removes all the boilerplate of traditional Flux frameworks
  • Unidirectional flow of information: Enforces the basic principles in flux
  • Follows the Flux Standard Action standard.
  • Designed to work in both the client and server side
  • Actively maintained and being used in production.
  • Based on ES6 classes

Code example

With alt-ng, action results are automatically dispatched to methods in the stores:

alt.js

import Alt from 'alt-ng';

// create our singleton instance
export default new Alt();

UserActions.js

import alt from './alt';

// Mock remote API
// The real thing would connect to the server using Fetch API or a polyfill
const MyUserApi = {
  fetch: function(userId) {
    console.log(`Retrieving user ${userId}`);
    return Promise.resolve({
      id: userId,
      name: `User ${userId}`
    });
  },
  save: function(user) {
    console.log(`Saving user ${user.id}`);
    return Promise.resolve(user);
  }
}

export default alt.createActions('UserActions', {

  // Promises are transparently resolved before dispatching to the Store
  fetchUser: function(userId) => {
    return MyUserApi.fetch(userId);
  }

  // more Promises
  saveUser: function(user) => {
    return MyUserApi.save(user);
  }

  // other values are dispatched directly to the Store
  onChange: function(attributeName, value) {
    let value = {};
    value[attributeName] = value;
    return value;
  }

})

The action methods will be used as constants while binding.

UserStore.js

import alt from './alt';
import UserActions from './UserActions';
import Store from 'alt-ng/Store';

// This Store will contain the User that is being edited right now as its 'state' attribute.
// The Store methods will be notified when the actions are dispatced
class UserStore extends Store {

  constructor() {
    this.state = {
      user: undefined
    };
    this.bindActions(UserActions);
  }

  fetchUser(user) {
    this.setState({ user });
  }

  saveUser(user) {
    this.setState({ user });
  }

  onChange(userField) {
    this.setState({
      user: Object.assign(this.getState().user, userField))
    });
  }

}
const userStore = alt.createStore('UserStore', new UserStore());
export { userACtions, userStore };

The easiest way to use this Store is to inject state as properties to the view:

import UserStore from './UserStore';
import UserACtions from './UserActions';
import AltContainer from 'alt-ng/AltContainer';
import React from 'react';

class UserData extends React.Component {

  constructor() {
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  onChange(e) {
    UserActions.onChange(e.name, e.value);
  }

  onSubmit(e) {
    e.preventDefault();
    // after a successful page save, send the browser somewhere else
    UserActions.save(this.props.user).then(() => {
      location.href = '/users';
    })
  }

  render() {
    const user = this.props.user;
    return (
      <form onSubmit={this.onSubmit}>
        <label>
          Name:
          <input name="name" value={user.name} onChange={this.onChange}/>
        </label>
        <button type="submit" />
      </form>
    )
  }

}

class MyApp extends React.Component {

  render() {
    // inject userStore.state as UserData.props
    return (
      <AltContainer store={userStore}>
        <UserData />
      </AltContainer>
    )
  }

}

You can get the full story by reading the tutorial or the documentation.

License

Licensed under the MIT license

alt-ng is based on the great job by Josh Perez, the original author of Alt