I am slowing migrating from AngularJS to Angular(2+) and just stumbled across something.
In AngularJS, I used a lot of factories and services for sharing data across directives, controllers and other services. It is easy to update the service in one place and have it update everywhere else automatically.
However, I am trying to use a service in a similar manner in Angular 5 and "nothing is happening" when I change the service variables.
I've seen some solutions that involve creating functions that "pull" the new data or suggestions to update the "Angular change service" to bind events to the variable.
However, my app has many variables used in many locations. It doesn't seem correct that I have to subscribe to every single variable separately, within every single component that uses them, and change the service to emit a change for every single one.
Am I just missing something?
Thanks!!! Wayne
For Example:
A component for a home page.
import { Component, OnInit } from '@angular/core';
import { HomeButtonDirective } from '../home-button.directive';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
The directive for a button that is reused on the home page:
import { Directive, Input, OnInit, HostListener } from '@angular/core';
import { InfoService } from './info.service';
@Directive({
selector: '[appHomeButton]',
providers: [InfoService]
})
export class HomeButtonDirective {
@HostListener('click', ['$event']) onclick($event) {
this.info.showHome = false;
}
constructor(private info: InfoService) { }
ngOnInit() {
}
}
The app component. Will show the home page if showHome===true:
import { Component } from '@angular/core';
import { InfoService } from './info.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [InfoService]
})
export class AppComponent {
title = 'Testing a service';
showHome = true;
constructor(private info: InfoService) {
this.showHome = this.info.showHome; // this works...showHome becomes false per the service (see below)
}
}
And finally, the service:
import { getTestBed } from '@angular/core/testing';
import { Injectable } from '@angular/core';
@Injectable()
export class InfoService {
showHome = false;
}
It is easy to update the service in one place and have it update everywhere else automatically.?
Register the service with an Angular module rather than a component.
from Angular docs
Angular module providers
(@NgModule.providers)
are registered with the application's root injector. Angular can inject the corresponding services in any class it creates. Once created, a service instance lives for the life of the app and Angular injects this one service instance in every class that needs it.
To summarize
If we want an instance of a dependency to be shared globally and share state
across the application we configure it on the NgModule.
If we want a separate instance of a dependency to be shared across each instance of a component and it’s children we configure it on the components providers
property.