'getElementById returns "null" in ngFor loop element
So I am currently developing an application using Ionic-Angular.
Im using Angular *ngFor to create a number of objects to show in a slider like this:
<ion-slides #theSlides [options]="sliderConfig" id="peerSlide" >
<ion-slide *ngFor="let peer of peers; let i = index">
<img id="{{'x' + i}}">
<p>{{peer.firstname}}</p>
<p>{{peer.lastname}}</p>
<p>{{peer.status}}</p>
</ion-slide>
</ion-slides>
The ngFor loop works fine but when I'm trying to access the image element inside by getElementById to set the source of the image it returns null. This is the type script code which push the peer object into peers array:
this.peer_profile_ready.subscribe(
() => {
var peer = {
id: 1,
firstname: this.peerFirstName,
lastname: this.peerLastName,
status: this.peerStatus,
}
this.peers.push(peer);
var peerImage = < HTMLImageElement > document.getElementById("x0");
console.log('peerImage', peerImage)})
so now console returns null. I appreciate if you can tell what is wrong here and what is the best way to access an element inside ngFor loop. thank you
Solution 1:[1]
The issue with your code :
angular has not had the chance to run its "check modified data and update DOM" processing between the two instructions :
this.peers.push(peer);
var peerImage = < HTMLImageElement > document.getElementById("x0");
so when you ask for element x0, it is still absent from the DOM.
You would have to wait for the next ngAfterViewInit() event to have your code execute with a DOM which contains your x0 img node. See angular lifecycle hooks for more details.
What you probably should do :
if you need to update the fields of your <img> node, you should probably have your data layer provide the necessary data, not "inject" an html node in your data layer and update its fields from the javascript code.
For example : if you need to update the src of the image, add an src field in your data :
- example 1 : add an 'src' field in your 'peer' objects
// in your javascript code :
var peer = {
id: 1,
src: '/starting/img.png',
...
}
// in your html template :
<img id="{{'x' + i}}" [src]="peer.src">
- example 2 : have a function return the value for
srcfrompeer:
// in your javascript code :
getPeerImage(peer) {
if (this.state[peer.id] === "ok") {
return "ok.png";
} else {
return "questionmark.png";
}
}
// in your template :
<img id="{{'x' + i}}" [src]="getPeerImage(peer)">
Solution 2:[2]
I think executing the portion of typescrit code you shared, inside ngAfterViewInit(), is the best way to achieve what you want.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Elmehdi |
