1

I use lazy-loading modules, when I arrive on a page of my module, I use functions of a service which performs actions on a global variable of this service.

I have a function that load this global variable from my service. The problem is that no matter where I call this function in my module, the variable is not filled fast enough on the first display, and so I get errors because my variable is empty on the first display.I'm

I tried loading my variable in my module's constructor, but it still doesn't fill the variable fast enough for the first display.

In my service :

export class ReferenceService {

    parts: any;

    constructor(
        private http: HttpClient
    ) { }

    loadParts() {
        this.http.get(apiUrl.partsGet).subscribe(data => this.parts = data);
    }

    getParts() {
        return this.parts;
    }

}

In my module :

export class LaserfibreModule {
    constructor(private apiReference: ReferenceService) {
        this.apiReference.loadParts();
    }
}

In my component : console.log(this.apiReference.getParts()) // return undefined

I would like to find a way so that my component does not display until this variable "parts" is not filled

I found a temporary solution which is to call my "loadParts()" function in my app.component.ts, which works but if I do that, it's not really lazy loading anymore

I tried to use an APP_INITIALIZER in the provider of my module but it does not work

ZaRToP
  • 31
  • 5
  • 1
    You are asking to call a service, only after its module loads, but at the same time you are asking to get data from the this service, before the module loads. It's not possible!! Either call the service before module loads (it's still lazy loading, just moving an api to app.component.ts level, doesn't mean you whole module is loading off the bat), or let the module load, and call the service. You can show a loading indicator or empty screen in the module's template, until you get the response from the api. – Nehal Nov 29 '22 at 16:26
  • using *ngIf on your html should fix your problem. see solution by zailif – Rick Nov 30 '22 at 00:04
  • @Nehal I don't want to fetch data from my service before my module loads, but before module components load, but I found a solution with resolvers and Zailef's solution, thanks for your answer – ZaRToP Nov 30 '22 at 12:28

1 Answers1

4

Whether this answer will work is going to depend on how you have architected your Angular application, but you could potentially use a route resolver service. Route resolvers are used to prefetch data when routing to a component.

Here's a basic example of a route resolver service:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { Observable } from 'rxjs/Observable';

import { IProduct } from './product';
import { ProductService } from './product.service';

@Injectable()
export class ProductResolver implements Resolve<IProduct> {

    constructor(private productService: ProductService) { }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IProduct> {
        let id = +route.params['id'];
        return this.productService.getProduct(id);
    }
}

You can read the full docs here. There's more detail on how to wire it up, as the resolver needs to be added to the route definition for the component.

If you aren't using routing, or the above isn't suitable, another option would be to render the part of the component's template that is dependent on the data being populated when it's ready (you could show a loading spinner or something until then). You can use a simple *ngIf to achieve this - e.g:

<div *ngIf="parts">
 {{ parts.name }}
</div>
Zailef
  • 677
  • 1
  • 10
  • 13
  • 1
    I didn't know about resolvers, it's not really what I expected but I managed to adapt it to make my solution work, and it works very well, thank you very much – ZaRToP Nov 30 '22 at 12:25