Reactive programming in RxJs ft. Angular

Your whole life was a lie

Ankit kaushik
Level Up Coding

--

A thinking human and the settings in background

Throughout our careers most of us have been taught to write a set of instructions and get the job done. It was majorly focused on “HOW” instead of “WHAT” and that makes complete sense as well as it’s critical to learn how do you solve something and we can master the skills of writing the same in a better fashion in the next level. When I say writing it in a better way I refer to putting minimal cognitive load to the next developer working on it. Making things simpler for the next developer (and yourself in the future) to understand what's going on (what that piece of code does).

The Problem statement

User list using Angular material
  • Render a user list fetched from the API
  • Ability to add a new user (firstName, lastName and email)
  • Ability to update an existing user
  • Ability to delete an existing user

The Reactive first mindset

Thinking in terms of actions and states your component needs where everything is a variable (an observable stream) which could be thought of as function of some deltas and those deltas (which are again some streams) could be clubbed together using RxJs operators according to the relation or dependency they have. (For example sum$ = fn (delta1$, delta2$))

Actions

// fire this to add a new user
addUserAction$$ = new Subject<IUser>();
// fire this to delete a user
deleteUserAction$$ = new Subject<IUser>();
// fire this update a user
updateUserAction$$ = new Subject<IUser>();

Data retrieval members

private fetchedUsers$ = this.http
.get<IUser[]>('api/users');

private addUser(user: IUser) {
return this.http.post<IUser>('api/users', user)
.pipe(map(() => user));
}

private deleteUser(user: IUser) {
return this.http
.delete<IUser>(`api/users/${user.id}`)
.pipe(map(() => user));
}

private updateUser(updatedUser: IUser) {
return this.http
.put<IUser>(`api/users/${updatedUser.id}`, updatedUser)
.pipe(map(() => updatedUser));
}

User events

private userAdded$ = this.addUserAction$$.pipe(
switchMap((userToBeAdded) => this.addUser(userToBeAdded))
);

private userUpdated$ = this.updateUserAction$$.pipe(
switchMap((userToBeUpdated) => this.updateUser(userToBeUpdated))
);

private userDeleted$ = this.deleteUserAction$$.pipe(
switchMap((userToBeDeleted) => this.deleteUser(userToBeDeleted))
);

Here each user event is a function of triggered action and the API call. For example: userAdded$ is fn(addUserAction$$, addUserAPIRequest) and switchMap (RxJs operator) there is used to support the dependency between these 2 deltas to form the underlying userAdded$ state.

userEvent$ = merge(this.userAdded$, this.userUpdated$, this.userDeleted$);

Any of these event fires, the userList$needs to be updated as userList$ is function(dependency) between fetchedUsers$ and userEvent$

userList$ = this.userEvent$.pipe(
startWith(null),
switchMap(() => this.fetchedUsers$)
);

Here’s the link to the complete demo👇

I’ll be coming up with more scenarios to cover using the same reactive approach, your appreciation would definitely motivate. Thanks!😊

--

--