question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ngTemplateRef + colvis-button (Turn columns "visible":false) - TypeError: Cannot read property 'appendChild' of null

See original GitHub issue

IMPORTANT: I will try to deliver a stackblitz or minimal reproduction project later. I tried to create a stackblitz or use the stackblitz “angular-datatables-gitter” but I couldn’t get them to work with ngTemplateRef. Please don’t close this issue immediately!

🪲 bug report

I have a datatable that gets initialized within “ngAfterViewInit”. It uses “ajax” to gather data. I use the datatable “server side the angular way”. I have activated the “buttons” plugin to use “colvis” and “stateSave: true”.

In my use-case I need one column with a ngTemplateRef. I initialize “this.columns” and put the column with ngTemplateRef at the end, then pass it into “dtOptions”. The Datatable initializes fine.

Once I turn one column before my ngTemplateRef column invisible and reload the page, the datatable crashes with this error:

TypeError: Cannot read property 'appendChild' of null
    at EmulatedEncapsulationDomRenderer2.appendChild (platform-browser.js:670)
    at angular-datatables.directive.js:79
    at Array.forEach (<anonymous>)
    at S.fn.init.rowCallback (angular-datatables.directive.js:68)
    at jquery.dataTables.js:6682
    at Function.map (jquery.min.js:2)
    at _fnCallbackFire (jquery.dataTables.js:6681)
    at _fnDraw (jquery.dataTables.js:3503)
    at _fnAjaxUpdateDraw (jquery.dataTables.js:4169)
    at jquery.dataTables.js:4009
    at callback (jquery.dataTables.js:3901)
    at SafeSubscriber._next (material-template-dt.component.ts:132)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)
    at Subscriber._next (Subscriber.js:72)
    at Subscriber.next (Subscriber.js:49)
    at CatchSubscriber._next (Subscriber.js:72)
    at CatchSubscriber.next (Subscriber.js:49)
    at MapSubscriber._next (map.js:35)
    at MapSubscriber.next (Subscriber.js:49)

🔬 Minimal Reproduction

IMPORTANT: Will deliver stackblitz or project later!

  • Create a datatable
  • Example code:

x.component.ts

dataTableActions: Array<DataTableAction> = [
    {
      cmd: "edit",
      label: "Bearbeiten"
    },
    {
      cmd: "delete",
      label: "Löschen"
    },
  ];

  @ViewChild('dtActions') dtActions: TemplateRef<ActionsComponent>;

.
.
.

ngAfterViewInit(): void {
    this.columns.push(...[
      {
        title: "Name",
        data: "name"
      },
      {
        title: "Age",
        data: "age"
      },
      {
        title: "Info",
        data: "info"
      }
    ]);

    if (this.dataTableActions.length > 0) {
      this.columns.push({
        title: "Aktionen",
        data: null,
        orderable: false,
        searchable: false,
        defaultContent: "",
        ngTemplateRef: {
          ref: this.dtActions,
          context: {
            captureEvents: this.onCaptureEvent.bind(this)
          }
        }
      });
    }

    this.dtOptions = {
      language: german,
      dom: '<l>Bfrtip',
      buttons: [
        {
          extend: 'colvis',
          columns: ':not(.noVis)'
        },
        'excel',
      ],
      columnDefs: [
        {
          targets: "_all",
          className: "valign-middle",
        },
        {
          targets: [0],
          className: "text-right noVis",
        },
      ],
      stateSave: true,
      serverSide: true,
      processing: true,
      searchDelay: 600,
      ajax: (dataTablesParameters: any, callback) => {
        this.service
          .getJsonLd().subscribe(resp => {
            callback({
              recordsTotal: resp['hydra:totalItems'],
              recordsFiltered: resp['hydra:totalItems'],
              data: resp['hydra:member']
            });
          });
      },
      columns: this.columns
    };

onCaptureEvent(event: DataTableActionsEvent): void {
    // Stuff
  }

x.component.html

<ng-template #dtActions let-data="adtData" let-emitter="captureEvents">
    <app-actions [actions]="dataTableActions" [data]="data" (emitter)="emitter($event)"></app-actions>
  </ng-template>

      <table id="material--template-dt" *ngIf="columns.length" datatable [dtOptions]="dtOptions" class="table table-striped w-100"></table>
  
  • Load the page
  • Use “colvis”-Button to hide one column before our ngTemplateRef column
  • Reload the page

🎱 Expected behavior

The Datatable should render fine.

🌐 Your Environment

  • node version: 16.4
  • angular version: 11.2.8
  • angular-cli version: 11.2.7
  • jquery version: 3.6.0
  • datatables version: ^1.10.20
  • angular-datatables version: 12.0.0

📝 Additional context

It seems like in the line 66-80 within angular-datatables.directive.js are the issue:

// Filter columns using `ngTemplateRef`
  var colsWithTemplate = columns_1.filter(function (x) { return x.ngTemplateRef && !x.ngPipeInstance; });
  colsWithTemplate.forEach(function (el) {
      var _a = el.ngTemplateRef, ref = _a.ref, context = _a.context;
      // get <td> element which holds data using index
      var index = columns_1.findIndex(function (e) { return e.data == el.data; });
      var cellFromIndex = row.childNodes.item(index);
      // render onto DOM
      // finalize context to be sent to user
      var _context = Object.assign({}, context, context === null || context === void 0 ? void 0 : context.userData, {
          adtData: data
      });
      var instance = self.vcr.createEmbeddedView(ref, _context);
      self.renderer.appendChild(cellFromIndex, instance.rootNodes[0]);
  });

I think after disabling some columns and reloading the page, there is a bug with referenced indeces. Naively spoken: The column of ngTemplateRef gets a certain index beforehand (index = 3), a column gets "visible: false, the column.length only goes to index 2 and then it tries to map everything to index 3 causing a null reference error.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:20

github_iconTop GitHub Comments

1reaction
shanmukhatejacommented, Sep 7, 2021

Hi @mtrzensky

bug confirmed. Let me see if I can work something out this weekend 😃

0reactions
shanmukhatejacommented, Sep 13, 2021

@mtrzensky yes and yes - an updated repo project as well as new issue would help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeError: Cannot read property 'appendChild' of Null in JS
The "Cannot read property 'appendChild' of null" error occurs for 2 reasons: Calling the appendChild() method on a DOM element that doesn't exist,...
Read more >
Uncaught TypeError: Cannot read property 'appendChild' of null
The "Cannot read property 'appendChild' of null" error occurs for 2 reasons: Calling the appendChild() method on a DOM element that doesn't ...
Read more >
Cannot read property 'appendChild' of undefined
I want to show the geoposition on a leaflet map lightning component. I enter an Id and get geolocation data accordingly.
Read more >
klaviyo form error "Cannot read property 'appendChild' of null
I'm having some issues with a signup form displaying on some page loads but not on others.
Read more >
L-Lin Angular-Datatables Statistics & Issues - Codesti
ngTemplateRef + colvis-button (Turn columns "visible":false) - TypeError: Cannot read property 'appendChild' of null, closed, 20, 2021-06-25, 2022-12-06 ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found