While working on an Angular project, you may encounter a situation where you need to completely reload a component, and the only apparent way to do so is to destroy and reload that component. This might fix errors such as:
- Data is not being refreshed properly when sent to the component's input property.
- The component is displaying stale content and does not receive its data from an input property at all.
As a rule of thumb, we recommend you not use this approach. However, in a very small set of edge cases, this may be the only viable way to resolve some issue, especially as a temporary tactical fix. In the sections below, we'll discuss when this type of approach is recommended, alternative approaches to take, and how to implement the code for this, both for destroying + reloading Angular components and standard HTML elements.
When Should this Approach be Used?
This type of approach is a dirty and hacky way to refresh content on the dom and should not even be considered an option unless:
The component in question is a 3rd party component which does not handle changes properly and whose codebase you have no control over.
The strategy of fully destroying and rerendering an Angular component should only be considered in this scenario and should only be used if all other attempts to properly pass data and rerender via normal means have failed. In the section below, we'll discuss some alternative approaches.
Alternative Approaches to Try First
Before proceeding with the destroy + recreate approach, let's try some alternatives which may resolve the underlying issue in a cleaner and more performant manner. Some of these points might not be applicable depending upon your particular scenario:
- Ensure the input property to the component is actually updating: the issue may actually be with the way data is being sent to the component, not to the component itself.
- Pass the data via observable properties: if data is being passed in with non-observable properties, try using a BehaviorSubject to store the value, and pass in the behavior subject with an async pipe to the component instead.
- Check if ngOnChanges is needed: if you own the component which is not updating properly, check to see if we need to add a hook to ngOnChanges. In some situations, the component will need to perform some action at the moment new data is passed in. If this is needed but missing, this may be the root cause.
- Check the documentation: if you are using a 3rd party component, Angular or otherwise, check its documentation to ensure that you are passing in data correctly and the way the component is expecting to receive it. Also check if there is any manual function invocation required once data is passed in.
How to Implement
If all of the attempts at resolution outline above have failed, then we can proceed with this implementation. To destroy and re-create the component, we will need to:
- Wrap the component or element in an ng-container.
- Create a property on the consuming component isVisible$. The default should be true.
- Create an *ngIf condition on the ng-container using isVisible$.
- When it is time to rerender, set the subject to false for a brief time, then set back to true.
In this implementation strategy, we introduce a small period of time where the component does not exist at all on the DOM. When the behavior subject value is set back to true, it is then re-created. In our example below, we use setTimeout to destroy the component, then almost immediately rerender it:
Alternatively, within the HTML markup, the conditional statement could be applied to the component itself instead of wrapping in an ng-container, if it doesn't already have an ngIf.
Change Detection
As a concluding remark, note that change detection was not used in this implementation.