Skip to content

An introduction to using pure Redux in TypeScript with Angular 2

Notifications You must be signed in to change notification settings

ng-book/angular2-redux-chat

Repository files navigation

Angular 2 Redux Chat

Angular 2 Redux Chat Join the chat at https://gitter.im/ng-book/ng-book

An Angular 2 chat app using Angular 2, Redux, Angular CLI, Webpack, TypeScript, Services, Injectables, Karma, Forms, SCSS, and tslint by the ng-book 2 team

This repo shows an example chat application using Redux and Angular 2. The goal is to show how to use the Redux data architecture pattern within Angular 2, using the core Redux library. It also features:

Try the live demo here

Angular 2 Redux Chat

Quick start

# clone the repo
git clone https://github.com/ng-book/angular2-redux-chat.git

# change into the repo directory
cd angular2-redux-chat

# install
npm install

# run
npm start

Then visit http://localhost:4200 in your browser.

Architecture

The app has three models:

  • Message - holds individual chat messages
  • Thread - holds metadata for a group of Messages
  • User - holds data about an individual user

Model Diagram

There are two reducers:

There are also three top-level components:

  • ChatNavBar - for the top navigation bar and unread messages count
  • ChatThreads - for our clickable list of threads
  • ChatWindow - where we hold our current conversation

Angular 2 Redux Chat

Components Subscribe to the Store

In this project, we're using the official Redux library instead of a wrapper or Redux-inspired spin-off. At the top of our app we create a new Redux Store and provide it to the dependency injection system. This let's us inject it into our components.

Our container components inject the Redux Store and subscribe to any changes. Consider this excerpt from the nav-bar which keeps the count of unread messages:

export default class ChatNavBar  {
  unreadMessagesCount: number;

  constructor(@Inject(AppStore) private store: Store<AppState>) {
    store.subscribe(() => this.updateState());
    this.updateState();
  }

  updateState() {
    // getUnreadMessagesCount is a selector function
    this.unreadMessagesCount = getUnreadMessagesCount(this.store.getState());
  }
}

You can see that in the constructor we inject our Store (which is typed to AppState). We immediately subscribe to any changes in the store. This callback will not be called unless an action is dispatched to the store, so we need to make sure we load the initial data. To do this, we call this.updateState() one time after the subscription.

updateState reads the state from the store (this.store.getState()) and then calls the selector function getUnreadMessagesCount (you can find the implementation of that here). getUnreadMessagesCount calculates the number of unread messages. We then take that value and set it to this.unreadMessagesCount. Because unreadMessagesCount is an instance variable which appears in the template, Angular will rerender this component when the value changes.

This pattern is used throughout the app.

Understanding how everything fits together with Redux can be tricky, but this code is heavily commented. One strategy to understand this code is to start at the components and see how they read the Store with selectors, dispatch actions, and follow that through the reducers. The other strategy is to get a copy of ng-book 2 where we explain each line in detail over ~60 pages.

State

The top-level state has two keys: users and threads:

interface AppState {
  users: UsersState;
  threads: ThreadsState;
}

interface UsersState {
  currentUser: User;
};

export interface ThreadsEntities {
  [id: string]: Thread;
}

export interface ThreadsState {
  ids: string[];
  entities: ThreadsEntities;
  currentThreadId?: string;
};

ThreadsState stores the list of Threads indexed by id in entities, as well as a complete list of the ids in ids.

We also store the id of the current thread so that we know what the user is currently looking at - this is valuable for the unread messages count, for instance.

In this app, we store the Messages in their respective Thread and we don't store the Messages apart from that Thread. In your app you may find it useful to separate Messages into their own Messages reducer and keep only a list of Message ids in your Threads.

Here's a screenshot using Redux Devtools of the initial state:

Angular 2 Redux Chat State Tree

Bots

This app implements a few simple chat bots. For instance:

  • Echo bot
  • Reversing bot
  • Waiting bot

Angular 2 Redux Chat Bots

Detailed Installation

Step 1: Install Node.js from the Node Website.

We recommend Node version 4.1 or above. You can check your node version by running this:

$ node -v
vv4.1...

Step 2: Install Dependencies

npm install

Running the App

npm start

Then visit http://localhost:4200 in your browser.

Running the Tests

You can run the unit tests with:

npm run test

Build Redux in TypeScript Tutorial

This repository contains a step-by-step tutorial on how to build a minimal-redux store in Typescript. You can read a blog post explaining this code here. You can also find the code in minimal/tutorial. The final result looks like this (with or without Observables):

Minimal Redux in TypeScript

Minimal Angular 2 Redux Integration

This repository also contains an example of a minimal integration of Redux with Angular 2 to build a counter app. You can also read about how to build this project here at the ng-book blog.

Minimal Redux and Angular 2 Counter

Series

This repo is part of a series of projects that discuss data architecture with Angular 2. You can find this same project implemented with Observable streams instead of Redux here:

Contributing

There are lots of other little things that need cleaned up such as:

  • More tests
  • Cleaning up the vendor scripts / typings

If you'd like to contribute, feel free to submit a pull request and we'll likely merge it in.

Getting Help

If you're having trouble getting this project running, feel free to open an issue, join us on Gitter, or email us!


ng-book 2

ng-book 2

This repo was written and is maintained by the ng-book 2 team. In the book we talk about each line of code in this app and explain why it's there and how it works.

This app is only one of several apps we have in the book. If you're looking to learn Angular 2, there's no faster way than by spending a few hours with ng-book 2.

License

MIT

About

An introduction to using pure Redux in TypeScript with Angular 2

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published