Sharing Data Between Components Using Service in Angular

In this video you will learn about sharing data between components using service in Angular. We can of course just write our API call inside component but then we can't really reuse this code because it's coupled with a component. Services in Angular help us to share data between different components in an easy and dry way.

In previous video we made our first API call to our fake json-server. If you didn't see that video go check it now. It works all fine but we have 2 problems here. First, if we want to fetch users in other place we need to write this code again. And second our component knows now too much. It has not only view logic but all logic fetch logic. And it will be even worse when we add here delete and add API calls.

This is why we have services in Angular. So what is services? Nothing difficult. It's just a class with methods. We can inject it in different components and reuse methods from it. It's not only related to working with API. we can put there any logic that we want.

Let's try to move getting of users to the service first. First we need a service folder in app.

users.service.ts

import {Injectable} from '@angular/core'

@Injectable()
export class UsersService {
  foo(): string {
    return 'foo'
  }
}

So here we created basic UsersService. The most important part here is Injectable. It will give us possibility to use this class inside Angular. What is more important is round brackets because without them you will get really magic errors.

Now let's try to add use it inside our app.component.

constructor(private http: HttpClient, private usersService: UsersService) {}

ngOnInit(): void {
  console.log(this.usersService.foo())
}

In browser now we get an error

No provider for UsersService!

because we didn't bind our Service to the module. To do that we need to add our service to providers list of the module where this component is declared.

@NgModule({
  ...
  providers: [UsersService],
  ...
})
export class AppModule {}

Now we don't have any errors and we see foo in browser. Let's move how getting to the service.

@Injectable()
export class UsersService {
  constructor(private http: HttpClient) {}

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

Now it may be complicated. So we want to say what we are getting back. And this thing what htt.get gives us where we can use subscribe later is called Observable. Inside Observable in tags we can specify what type of data use are getting back. The problem here is that this.http.get gives back in typings Observable Object and we need to manually tell Typescript what we get back. This is why this code looks a bit verbose.

Now we can use getUsers function inside our component.

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

As you can see, everything is working exactly as before but now our communication with API is inside service and we can reuse it everywhere. Also our component doesn't know anything about fetching from API. It just knows that there is a stream which give correct data back.

Let's make a removing API call also now.

removeUser(id: string): Observable<{}> {
  return this.http.delete(`http://localhost:3000/users/${id}`)
}
removeUser(id: string): void {
  this.usersService.removeUser(id).subscribe(() => {
    this.users = this.users.filter((user) => user.id !== id)
  })
}

Here we created one more method inside our service and called it inside removeUser with subscribe. In this case we are sure that first we get the successful response and only then we change our UI.

addUser(name: string, age: number): Observable<UserInterface> {
  return this.http.post<UserInterface>('http://localhost:3000/users', {
    name,
    age,
  })
}
addUser(userName: string): void {
  this.usersService.addUser(userName, 30).subscribe((res: UserInterface) => {
    this.users.push(res)
  })
}

Here we created a new addUser post method and passed correct data from our component.

As you can see now we don't need to generate ID because we get it from API and everything is working in the same way.

In this video you learned on the real example how to write services in Angular. And of course you can write any functions or variables inside services and not just API calls.

Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!

📚 Source code of what we've done
Did you like my post? Share it with friends!
Don't miss a thing!
Follow me on Youtube, Twitter or Instagram.
Oleksandr Kocherhin
Oleksandr Kocherhin is a full-stack developer with a passion for learning and sharing knowledge on Monsterlessons Academy and on his YouTube channel. With around 15 years of programming experience and nearly 9 years of teaching, he has a deep understanding of both disciplines. He believes in learning by doing, a philosophy that is reflected in every course he teaches. He loves exploring new web and mobile technologies, and his courses are designed to give students an edge in the fast-moving tech industry.