Home > Back-end >  Waiting for array from another class to be loaded
Waiting for array from another class to be loaded

Time:02-16

I've been searching for a while trying to figure this out, I am most likely missing an obvious answer.

I have arrays of various types that get loaded in an injectable class when the app starts, data is loaded from backend api

Loading of the data is fine, I call the api and subscribe for the response, load it and away we go

But I have some components later on that depend on those lists having data as I may need to filter them in their OnInit's, how can I check/wait for those lists to be loaded?

ItemList class:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})

export class ItemList  {
  ....
  ....
  public  oneList: Map<string, string>;
  public  twoList: Object[];
  ....
}

InitLoader class:

import { Injectable } from '@angular/core';

import {HttpClient} from "@angular/common/http";
import { ItemList } from '../_common/constant/item-list';

@Injectable()

export class InitLoader {
       constructor(private httpClient:HttpClient,
                   private itemList:ItemList) {}

       public load() {
            ....
            ....                
            this.httpClient.get(url)
               .subscribe( res =>{
               ...
               ...
               this.itemList.oneList = res['oneListData'];
               this.itemList.twoList = res['twoListData'];
               ...
               ...
           }

       }
   }

In my app.component.ts I call the load() method

export class AppComponent implements OnInit  {

      ...
      ...        
      constructor(private translate: TranslateService,
                  private router: Router ,
                  private initLoader:InitLoader,
                  private items:ItemList )  {  

                 this.initLoader.load();
       ....
       }

Then finally in a page component where I would like to use one of the lists, I need to do some work/filtering of a list in the ngOnInit(), which if the data hasn't loaded yet I will have issues

import { ItemList } from '../_common/constant/item-list';

@Component({ 
      selector: 'page-one',
      templateUrl: './page-one.component.html',
      styleUrls: ['./page-one.component.less']
})
export class PageOneComponent implements OnInit {

    constructor( public router: Router,
        public items:ItemList) {
    }

    public ngOnInit() {

        this.items.oneList.filter(x => x.value == "blah");
}

So in my PageOneComponent how can I check and wait for this list to be loaded so that I can then filter? This is in a modest sized project that is pretty far along with many other components that rely on these lists, so hoping to avoid some major restructuring

CodePudding user response:

You could create a BehaviourSubject of the fields that you require in PageOneComponent in your InitLoader Service. When you get the response in your InitLoader load method, push that data into the BehaviourSubject. Also, create a getter for that BehaviourSubject for easy access.

Then in your PageOneComponent, use the getter of that BehaviourSubject to get the value only when it is loaded, or wait for it while being it is loaded using the subscribe method.

InitLoader Service

   itemList$: BehaviorSubject<any> = new BehaviorSubject(undefined);

      this.httpClient.get(url)
               .subscribe( res =>{
               ...
               ...
               this.itemList.oneList = res['oneListData'];
               this.itemList.twoList = res['twoListData'];
               this.itemList$.next(this.itemList);
               ...
               ...
           }

    getItemList(): BehaviorSubject<any> {
        return this.itemList$; 
    }

PageOneComponent

import { ItemList } from '../_common/constant/item-list';

@Component({ 
      selector: 'page-one',
      templateUrl: './page-one.component.html',
      styleUrls: ['./page-one.component.less']
})
export class PageOneComponent implements OnInit {

    constructor( 
        public router: Router,
        public items: ItemList,
        private initLoader: InitLoader) {}

    public ngOnInit() {
       this.initLoader.getItemList().subscribe(
          resp => { 
             if(!resp) { 
                console.log(resp);
                //Do your filtering etc here
             } 
          }
       );
    }
}
  • Related