Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject service as singleton for all components in Angular 4

Sorry if duplicate, I've read related posts, but didn't find (or didn't understand) an answer.

I have a service that is used by many components and I want it to be a singleton for all components (throughout all app). This service must send a request and get data once and then share this data among other components.

Here's some code as example:

app.module.shared.ts

import { MyService } from '../services/myservice';

@NgModule({
    declarations: [
         //...
    ],
    imports: [
        //...
    ],
    providers: [
        MyService
    ]
})

myservice.ts

@Injectable()
export class MyService {
    shareData: string;

    constructor(private http: Http, @Inject('BASE_URL') private baseUrl: string) { }

    getSharedData(): Promise<string> {
        return new Promise<string>(resolve => {
            if (!this.shareData) {
                this.http.get(this.baseUrl + "api/sharedDara").subscribe(result => {
                    this.shareData = result.json() as string;                    
                    resolve(this.shareData);
                }, error =>  console.log(error));
            } else {
                resolve(this.shareData);
            }
        });
    }
}

example.component.ts (the example of usage)

import { MyService } from '../services/myservice';

@Component({
    selector: 'example',
    templateUrl: './example.component.html',
    styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {

    sharedData: string;

    public constructor(private myService: MyService,
        @Inject('BASE_URL') private baseUrl: string) { }

    ngOnInit() {
        this.myService.getSharedData().then(result => this.sharedData= result);
    }
}

Documentation says:

Dependencies are singletons within the scope of an injector.

As I understand that for each component its own instance of a service is created. Is it right? And how to make a single instance of a service for all components?

Thanks in advance.

like image 293
Ann_K Avatar asked Oct 03 '17 17:10

Ann_K


1 Answers

To use a service as a singleton with multiple components:

  • import it
  • add it to your components constructor

DO NOT add it as a Provider to your component.

import { Service } from '../service';

@Component({
  selector: 'sample',
  templateUrl: '../sample.component.html',
  styleUrls: ['../sample.component.scss']
})
export class SampleComponent implements OnInit {

  constructor(private _service: Service) { }

To use a service as a new instance in each component you utilize it in:

  • import it
  • add it to the components constructor

DO add it as a Provider to your component

import { Service } from '../service';

@Component({
  selector: 'sample',
  templateUrl: '../sample.component.html',
  styleUrls: ['../sample.component.scss'],
  providers: [Service]
})
export class SampleComponent implements OnInit {

  constructor(private _service: Service) { }
like image 196
James Cummings Avatar answered Sep 17 '22 19:09

James Cummings