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' }))
);
}