Angular Services
Tags: javascript, webdev, angular, typescript
Published: 2022-06-05 02:47:34

Services are nothing but classes with a particular function for example fetching or providing data to other componenets
Dependency Injection 
Dependency injection is nothing but using the services in other components with loosely coupled so that changes can be easily made
DI conists of mainly 5 modules
consumerrs
prodivders
di token
depeendency
injector
It is responsibility of injector to provide and resolve the services and dependencies to the requested components
we register the service using providers array either at module level or at component level 
di token is an unique identification token with which injector identofies the serive and provides the instance of service to requested components
dependency is the service
consumers are nothing but componenets or directives or pipes which requires the service 
Asking for service in a component using DI
constructor(private productSercie:ProductService){}
we use @Injectable() if we need other service, if any other decorator is already exising in class then we dont need @Injectable() decorator we simply can use the above constructor syntax 
Injecting service into another service
@Injectable() is used for consistency purpose in every service but in general we do not need if the service do not require any other service as dependency
for registering a service there is no option to add providers in service class the provider must be added either in module level or component level
So the service can be added to providers array in app.component.ts
Now the providers array is in app.component then the services are available only to app component and its child components, to make the services availalbe globally then we must move this providers array to @NgModule decorator

instead of adding to ngModele providedIn can be used providedIn:'root'


angular Injector 
ModuleInjector - rootModuleInjector - created when bootstraps the application this becomes part of moduleInjector - appModule get its own injector called rootModuleInjector

for every component have their own injector instance and providers array
ElementInjector -  for elements (components and directives)



@Inject -  this can be used as an alternatie for @Injectable()
@Inject takes injector token as parameter
@Inject(LoggerService) private loggerService

angular Providers
angular providers helps us to register classes, functions or values with a token

4ways of creating a dependecy
useClass
useValue
useFactory
useExisting

angular providers is an array of instructions 

providers: [ProductService] this is shorthand notation for providers :[{ provide: ProductService, useClass: ProductService }] this
where provide - is a token and can be type,string or instance of InjctionToken
where second one -  It tells Angular how to create the instance of the dependency. The Angular can create the instance of the dependency in four different ways. It can create a dependency from the existing service class (useClass). It can inject a value, array, or object (useValue). It can use a factory function, which returns the instance of service class or value (useFactory). It can return the instance from an already existing token (useExisting).
string type
{provide:'PRODUCT_SERVICE', useClass: ProductService }, 
 {provide:'USE_FAKE', useValue: true },   
 {provide:'APIURL', useValue: 'http://SomeEndPoint.com/api' },
@Inject('PRODUCTSERVICE') private prdService:ProductService,
Injection token type

 
export const API_URL= new InjectionToken<string>(''); 

providers: [ 
    { provide: API_URL, useValue: 'http://SomeEndPoint.com/api' }
]PI_URL, useValue: 'http://SomeEndPoint.com/api' }
]
constructor(@Inject(API_URL) private apiURL: string) { 
}
 


@optional - skips import of service if service not there instead of throwing error
@self -  only checks providers array of its component only if not found throws error
@skipSelf() - skips component providers and search for top level
@Host - limits the search to template only it does not even search in component ts file also
for example 
<div direcctiveName></div>
import service in providers array of directiveName and use the directive in component html
it looks for service in current component providers and also looks for dependency in template level in host component
Add the RandomService to the Providers of the GrandChildComponent. Because that is where DI looks first for dependency.


The second option is to add RandomService to viewProviders array of the ChildComponent.

providedIn - root
providedIn - moduleName
providersArray[] - ngModule
providedIn - any
providedIn - platform

concept of treeShaking