user3408531
user3408531

Reputation:

How to initialize a variable once on the app.module using a service and use it later in other components?

I have a list of objects to be generated once in the application startup from a backend API using a service, the question is how to initialize that list and access it from the other components?

For example, in app.module.ts, I want something like:

    export class AppComponent {
  title = 'General Title';
  myListFromServiceApi:[DataType]; 
  }

How to call this in mycomponent.ts

ngOnInit() {
this.myListFromServiceApi= ??
}

Edit

I already have the service, but I want to avoid invoking the service every time the component added to a view, i.e call the service once in the lifetime of the application if that is possible, how can I achieve that?

Upvotes: 0

Views: 1543

Answers (2)

robert
robert

Reputation: 6152

See this stackblitz. Generally you have one sharedService. That will request the data once and store it as a local variable. Two other components (first and second) only Inject the service in the constructor and keep a reference to the member variable inside a sharedService. This way http call goes out only once. Invoked in:

  ngOnInit() {
    this.sharedService.getDataOnce();
  }

Upvotes: 1

Jan Wendland
Jan Wendland

Reputation: 1440

You could use the rx operator share that prevents a sideeffect (http request in your case) from being executed multiple times on subscription of multiple subscribers and return an observable that's piped through a share from a service, i.e. DataTypeService:

export class DataTypeService {

  dataTypes$: Observable<DataType>;

  constructor(private http: HttpClient) {
    this.dataTypes$ = this.http.get('/api/datatypes').pipe(share());
  }

  getDataTypes() {
    return this.dataTypes$;
  }
}

In your components you could then inject the DataTypeService, subscribe to the observable returned by getDataTypes() and the request would only be executed once.

constructor(private dataTypeService: DataTypeService){
   this.dataTypeService.getDataTypes().subscribe(dataTypes => {
       this.myListFromServiceApi = dataTypes;
   })
}

If you only wanna work with those data types in your template you could also directly store the observable returned by getDataTypes() on your component and utilize the async pipe

Upvotes: 2

Related Questions