In an Angular component, I display real-time data in a very complex way that requires the use of ElementRef
for various purposes supporting UI interaction.
this.elRef.nativeElement.querySelector('.my-element')
As a result, I am running into a few rare use cases when referencing an element this way throws a null
error because the element is either not yet accessible in the DOM or had been previously removed due to real-time data updates inside an *ngFor
.
To prevent errors, I am checking the native element for null
:
if(this.elRef.nativeElement.querySelector('.my-elment') != null) {
// reference or set style on this element
}
This works fine, but is there a better approach? I have wound up with a lot of these if
statements throughout my component as a result.
I have made every effort to avoid touching the DOM and to avoid running into the possibility for an element to be null
otherwise in my template, but I am stuck with some rare cases that are just unavoidable.
Any advice greatly appreciated.
If at all possible, try to eliminate or minimize the use of ElementRef
. The ElementRef
docs state:
Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you can take a look at Renderer2 which provides API that can safely be used even when direct access to native elements is not supported.
Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.
If an ElementRef
is unavoidable and there are cases where the ElementRef
will be null
, then the best you can do (without resorting to added complexity) is to use a little syntactic sugar and refactoring.
1. Use a short variable reference
const myEl = this.elRef.nativeElement.querySelector('.my-elment');
if (myEl != null) { }
2. Use a notNull()
function to make code cleaner and refactor logic that requires the ElementRef
into a subroutine.
export function notNull(x: any): boolean {
return x != null
}
const myEl = this.elRef.nativeElement.querySelector('.my-elment');
notNull(myEl) ? doSomething(myEl) : false;