Instructor: In this example here, we have the app component, which uses an app-person component inside its template. That app-person component injects here a people service, and that invokes here the people service getPerson method to display here a person.
In turn, the getPerson method of that people service is quite simple. We have here a name. Basically, the getPerson simply returns an object and references this name here, which is then being shown here by our app-person component.
What we would like to do now is to learn how we can scope a service to a certain component subtree, and to basically override it with a different kind of service. First of all, let's create here a new component. Let's call it woman.
That woman component does very much the same as that person component does. It gets an instance of that people service. We have here also person property. Here we do this.person = this.people.getPerson. We obviously need here to inject that service, import it from the person service.
Up here, let's do something like this. Let's say woman, just to know we are in a woman component here, and visualize that person again by simply showing its JSON structure.
Let's jump back to the app component and visualize our new app-woman component. Let's have a look. Great. We see that we get the same value, because both component actually get an instance of that person service. Therefore, we will get the same value inside here.
Let's now generate a new service, which we call woman service. We get here that woman service. What that woman service does is simply extending that people service. Then we basically override that getPerson method. We get here a person, and then we'll say person.name = Katie, and person.gender = female. Then, return that person.
TypeScript complains here because we don't match the structure. Let's simply return here any, and we should be fine to go. This person service is actually registered here on our module, just as the people service, and so they're both exposed globally on our app module.
Now let's go back to our woman component. You can see it still gets here the people service, and it also displays that same object from that people service, just as we expect. What we're going to do now is to basically override that people service.
We do it not in the module level, but in the component level. We have providers property here, as well, which works identically as the one in the NgModule, but it is scoped to this component and its children. Let's demonstrate that.
We create here the provide and say, whenever you see a people service, use the class woman service instead. If I save this, we will immediately see that this component here, which is displayed below the app component here, all get now an instance of an object, which comes from that woman service, which we just created here. Basically, we manipulate it in this way.
Most interestingly also, if we go to the app component and we use that same app-person component here, and we bring it here nested into the template of our woman service, that same one will also get now the instance from that woman service. Although, inside app-person, we simply inject here the people service, just as before. We didn't change that to woman service.
Here, we can basically see the hierarchical nature of the dependency injector in Angular. What happens here is that we have, at the very top, the app-root component, which is our app component. Then we have the app-person component which we gave it. Then we have the app-woman. Below, we did include, again, that app-person component.
We have one module here, which is basically registered at the very top. Globally, we inject here that people service. Inside the component tree, at some level, we say whenever you see that people service, which is just what we did, use that woman service instead.
From that component tree onwards, all its children and the component itself will then get an instance of this service, instead of the global people service.