3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 3

The Ngxtension Library and Connect

Automatically connect observables to signals

EXTENDED

Installing Ngxtension

Alright, let’s calm things down a bit now. We are actually going to use the connect function in this lesson, which is considerably easier than understanding how to build the thing.

The connect function is just one of the utilities found in the ngxtension library. Although it might seem wasteful to install an entire library for just one function, the library is structured to use secondary entry points such that when your Angular application is built tree-shaking will take care of removing code for all the rest of the functions that you aren’t using.

In this lesson, we will just be talking about the general usage of the connect function and in the following lessons we will refactor some of our existing code with it.

If you want, you can install this in the Quicklists application, or any other demo application, and have a play around with it:

ng add ngxtension

First, we are going to get the basic idea of how this works, and how it simplifies things for us. If you read through the entirety of the last lesson, then you might already have a decent idea of how this can be used.

Then in the coming lessons we will refactor the applications we have already built with this new approach — don’t worry, it’s actually quite easy because this utility is very much in line with the philosophy we have been using.

For our last application build, we will use this approach from the beginning. If you’re feeling comfortable with the general ideas we have been using for state management, then I would advise that you also just generally use this approach from now on as it removes a whole lot of boilerplate for us. If you don’t like it, feel free to continue using the approach we have been using.

Using the connect function

Let’s suppose we have a state signal that looks like this:

export type LoginStatus = 'pending' | 'authenticating' | 'success' | 'error';

interface LoginState {
  status: LoginStatus;
}
  // state
  private state = signal<LoginState>({
    status: 'pending',
  });

Let’s also suppose we have some sources that looks like this:

  // sources
  error$ = new Subject<any>();
  login$ = new Subject<Credentials>();

  userAuthenticated$ = this.login$.pipe(
    // ...snip
  );

With our normal approach we might set up some reducers like this:

  constructor() {
    // reducers
    this.userAuthenticated$
      .pipe(takeUntilDestroyed())
      .subscribe(() =>
        this.state.update((state) => ({ ...state, status: 'success' }))
      );

    this.login$
      .pipe(takeUntilDestroyed())
      .subscribe(() =>
        this.state.update((state) => ({ ...state, status: 'authenticating' }))
      );

    this.error$
      .pipe(takeUntilDestroyed())
      .subscribe(() =>
        this.state.update((state) => ({ ...state, status: 'error' }))
      );
  }
EXTENDED
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).