Hi everybody! I’m facing a challenge trying to accomplish this. I have a component which is being rendered with a selector. My problem is that this component make some heavy async work on ngOnInit(). This leads to a malfunction of my application in poor internet environments.
The thing is, my selector of the component is wrapped around a ngIf, but if I don’t put the selector on the html the component is not being instantiated and no data is retrieved. And if I put the selector in the html the component is rendered before data is available.
I have tried some solutions but none work for me.
Show I be able to make new myProblematicComponent() and send an event from the component when the data is loaded? But if I do this, how I render the component in my view? I suppose if I just push the selector in the view other data is being fetched instead the first one.
I’m afraid that’s not a solution. Also, I have never said the hard logic relies on fetching data from a server. In fact, it mostly relies on operations I do on a local SQLite.
Maybe I don’t understand your problem. If you have a delay, you can show spinner or any text, like “Loading…”. If you want to preload data, you must use a service and call it before. Not hard, just choose your way.
Custom-card is the selector for my problematic component. If I load the data, and then set: this.isDataAvailable = true
Then, once <custom-card></custom-card> is instantiated in my view it does not have the data available from the component.
On the other hand, if I delegate the data loading in my component ngOnInit() (for example), then the data is available to the component but I have timing problems in poor network environments due to the time it takes to load the data.
Use a service for getting the data before showing the custom-card component, then retrieve the data inside the component.
Change *ngIf for [hidden] so that the component does exists but it isn’t shown, then you can retrieve the data from the constructor or ngOnInit() method.
My recommendation is 1, you should use a service to separate controller logic from model, that also allows for retrieving the data from any part of the app (including the parent component) to then showing the child and in it showing the gathered data.
If you call the component from a HTML selector this is the flow:
<custom-selector></custom-selector> -> component ngOnInit call to service -> wait -> component HTML is rendered into the parent view without data -> wait -> wait -> data is available and rendered into the view
If you retrieve the data and wait until it is finished, how then you render into the view using custom-selector?
If you retrieve the data in the parent before showing the child, you only need the service to be in the parent providers array, that way it will be available to both so you can ask the service to gather data from the parent, then when data is available show the child and in child retrieve the data from service, which is provided by the parent.
Hi again!! Yes custom-selector is the child. Just a component, not a “page”.
That way of calling the service from the page, instead of in the component is not the anti-pattern of components? I mean, it is supposed a component should be reusable and self-contained (of course if we don’t take in mind the service). Am I wrong and the data should be retrieved from the “page” (the parent)?
It should be reusable and self-contained, but since you need the data to be available before rendering, pre-fetching with the parent isn’t wrong, just use the service in both, call the gather logic in parent and in child just ask if content is already fetched, if not fetch, but if it does just use it.
That way the component is self contained, you just tell the parent to ask the server to fetch ahead of time the data of the children.