dickensaround
dickensaround

Reputation: 125

Initializing an Array of ElementRefs in Angular

I’m refactoring a video chat app that I’m building using Angular 12, and I’ve run into what is probably a simple question that I’m not having much luck finding an answer to.

When I send the video and audio output to my display components via an ElementRef, I’ve been using a static name for the variables in the video service, something like…

video.service.ts

localParticipant: elementRef
remoteParticipant1: elementRef
remoteParticipant2: elementRef

…then linking them to their display components in the AfterViewInit lifecycle hook.

all-remote-participants.component.ts

@ViewChild('remoteParticipant1', { static: false }) remoteParticipant1: ElementRef;
@ViewChild('remoteParticipant2’, { static: false }) remoteParticipant2: ElementRef;

  constructor(private videoService: VideoService) {}

ngAfterViewInit() {
  this.videoService.remoteParticipant1 = this.remoteParticipant1
  this.videoService.remoteParticipant2 = this.remoteParticipant2
}

This works fine when you have a fixed number of participants, but since you can have “n” number of remote participants, what I wanted to do was create an array of ElementRefs named something like…

video.service.ts

remoteParticipant: elementRef[]

...so I can do...

remoteParticipant[0]
remoteParticipant[1]

…which would allow me to have a factory of display components and give me more flexibility.

remote-participant.component.ts

@Input() participantId: number
@ViewChild('remoteParticipant', { static: false }) remoteParticipant: ElementRef;

  constructor(private videoService: VideoService) {}

ngAfterViewInit() {
  this.videoService.remoteParticipant[this.participantId] = this.remoteParticipant
}

What I can’t figure out is what to put in the parentheses to push elementRefs onto the array. I’ll list my results below of what I’ve tried.

The variable is initialized as:

remoteParticipant: ElementRef[];

I’ve tried:

This creates the ElementRefs but they're empty, so you can't address nativeElement:

remoteParticipant.push({} as ElementRef)

Builds an array of nulls, which doesn't work:

remoteParticipant.push(null)

All of the rest are empty arrays:

remoteParticipant.push([])
remoteParticipant.push({})
remoteParticipant.push()

Any help is appreciated!

Upvotes: 2

Views: 1264

Answers (1)

Chaka15
Chaka15

Reputation: 1361

There's just a thing for this. You should use decorator @ViewChildren.

It returns QueryList and you can access multiple elements inside it. The @ViewChildren decorator supports directive or component type as parameter, or the name of a template variable. Read more about it on https://angular.io/api/core/ViewChildren.

You can also safely remove { static: false } since it's a default.

Adjust this answer for your needs, but it should look like this ->

@ViewChildren('remoteParticipants') remoteParticipant1: QueryList<ElementRef>;

Then you can access to length of this array of ElementRef, first element, last one...

Upvotes: 2

Related Questions