3
votes

I am developing a web application using angular dart.

I am trying to find a 'div' element inside the component using document.querySelector() and I am trying to modify(add some content to) its body.

But it doesn't seem to find the 'div' element.

Here is my html:

<ng-container *ngFor="let item of list">
  <ng-container *ngIf="item.canShowChart">
    <div [id]="item.elementID" class="chart"></div>
  </ng-container>
</ng-container>

Here is my component method which tries to modify the 'div':

  void drawChart() {
    for (final item in list) {
      if (!item.canShowChart) {
        continue;
      }
      final DivElement _container = document.querySelector('#' + item.elementID);
      print(_container);
    }
  }

It always prints the '_container' as 'null'

I tried removing the ng-container and having only the 'div' in the page like below and it seems to work!.

<div [id]="item.elementID" class="chart"></div>

What is the problem?

TIA.

3
You'll probably be better off doing that inside the template. What exactly do you want to do to that div? - mbojko
@mbojko I am trying to draw a pie chart inside the container: ``` final DivElement _container = document.querySelector('#' + item.elementID); PieChart(_container).draw(result.chartData, chartDrawingOptions); ``` - Sabareesh

3 Answers

4
votes

It is not working because as at the time you used 'querySelectorAll', angular had not loaded ng-container to the DOM yet. You should put your code in the 'AfterViewChecked' lifecycle hook.

export class ImageModalComponent implements OnInit, AfterViewChecked{
  //AfterViewChecked
  ngAfterViewChecked {
    void drawChart() {
    for (final item in list) {
      if (!item.canShowChart) {
        continue;
      }
      final DivElement _container = document.querySelector('#' + item.elementID);
      print(_container);
    }
  }
 }
}

Make sure to import 'AfterViewChecked' like so;

import { Component, OnInit, AfterViewChecked } from '@angular/core';
1
votes

You can make it a separate component, let's call it app-chart:

<ng-container *ngFor="let item of list">
  <app-chart *ngIf="item.canShowChart" [item]="item">
  </app-chart>
</ng-container>

In the AppChartComponent declare necessary input(s), and inject ElementRef in the constructor:

@Input() item: any;
constructor(private ref: ElementRef) {}

this.ref.nativeElement is how you can access the DOM element from inside.

0
votes

Never use querySelector to find elements in your template. Angular and DOM are two seperate paradigms and you should not mix them.

To find an element in your template, use a reference to an element.

<div #chartContainer class="chart"></div>

Then you can reference the div from your code.

See https://itnext.io/working-with-angular-5-template-reference-variable-e5aa59fb9af for an explanation.