Rxjs Streams in Angular - Normalizing Data (Map and Pipe Operator)

In this video you will learn what are RxJS streams in Angular. We will check on the real example how convenient it is to use RxJS map and pipe methods for normalizing data inside our service from observables which we are getting from API.

Introduction

Hi I'm Oleksandr Kocherhin from monsterlessons-academy, where I'm teaching you how to become a developer or improve your skills of being a developer in learning by doing way. And if you are new here don't forget to subscribe and I will link everything that I'm mentioning in the description.

Just to remind you this video is part of the free angular for beginners series So let's get started.

Content

In previous video we implemented several API requests. If you didn't see that video don't forget to check it out. But for sure all this Observables and subscriptions is not super clear for you.

Let's start from scratch. In Angular one of the core things was to use streams as a core part of Angular. What are streams at all? So the main idea is that you can create stream and then subscribe to the changes that happened in this stream. It's exactly how promises are working with the difference that promise happens only once, you just come in then and thats it, but in subscribe on the stream you can come again and again.

It works really good because all your components are subscribed to some streams and they are simply rerendered when our streams value changes.

So streams are just a architectural solutions to the part of problems. It's not a silver bullet and there are pros and cons as everywhere. Inside Angular streams are implemented with RxJs library and you must learn it at some point to write good Angular code. And this is one more thing why Angular is more difficult to learn that other frameworks.

Let's look on our service we used there such thing as Observable. So Observable is something that we can observe. And httpClient is fully working on streams with RxJS. This is why as a result of httpClient call we get back Observable.

As you saw the easiest usage of streams is just an Observable, for example from httpClient and a subscribe function where we pass a callback. This is exactly from where everybody are starting in RxJS and it's completely fine.

But Rxjs gives us much more possibilities. The common usecase is to normalize data that we get from API in the format which is easier for us to work with.

Let's say that we get users and format is not like we want.

getUsers(): Observable<UserInterface[]> {
  return this.http.get<UserInterface[]>('http://localhost:3000/users').pipe(
    map((users) => {
      return users
    })
  )
}

The first thing which is new here is pipe operator. The idea is that we can modify our stream and then in subscribe we will get other value. To modify the stream we always use .pipe at the end and inside pipe we can write comma separated functions which will be called one by one on the data when we get them.

And the most popular function for using in pipe is map. But here is super important point. map inside rxjs is not working like in javascript. It's not going through array and maps each value. It just maps the result that we get back. As you can see here is why the argument of map function is users and not users. Because we get here the whole array and not each element.

So as you can see we didn't do anything here . We simply wrote pipe with map inside and returned data as it is.

As you can see in browser, everything is working as before.

But not inside this map we can just modify this array as in plain javascript and return the result. Then the value that we get in subscribe later will change.

getUsers(): Observable<UserInterface[]> {
  return this.http.get<UserInterface[]>('http://localhost:3000/users').pipe(
    map((users) => {
      return users.map((user) => ({
        id: user.id,
        name: user.name,
        age: `${user.age} years old`,
      }))
    })
  )
}

Here we just went with map through users and modified the data. And what is actually good we directly get an error from Typescript. In our getUsers we defined that we get back a Observable with UserInterface[]. Now we remapped age as number to string and it conflicts with interface.

Lets say that this what this was intended and we just change a property inside our interface.

this.usersService.getUsers().subscribe((res: UserInterface[]) => {
  console.log('res', res)
  this.users = res
})

If we write a console.log inside subscribe now you can see that we get modified data.

Call to action

In this video you learned some basics about rxjs and streams in Angular. Of course this is like 1% of RxJS knowledge. There is lots of other stuff like filtering streams, combining streams, merging several streams and much more.

If angular for beginners is too easy for you or you want more advanced stuff check my 14 hours Angular course where we create a real project from beginning to the end. Link is also in the description.

If you find this video helpful, don't forget to subscribe to this channel and hit subscribe button. And I see you in my next video.

🚨 Important

📚 References