Topic: TypeError: Cannot read properties of undefined (reading 'setDataSource')

allancmello pro asked 1 year ago


Expected behavior

The properties of undefined reading 'setDataSource' or not found.

Code sample of mdbootstrap:

import {Component, HostListener, ViewChild} from '@angular/core';
import {MdbTableDirective} from 'PATH-TO-MDB-ANGULAR';

@Component({
  selector: 'search-table',
  templateUrl: './search-table.component.html',
  styleUrls: ['./search-table.component.scss']
})
export class SearchTableComponent {
  @ViewChild(MdbTableDirective, {static: true}) mdbTable:MdbTableDirective;

  elements: any = [];
  headElements = ['ID', 'First', 'Last', 'Handle'];
  searchText: string = '';
  previous: string;

  constructor() { }

  @HostListener('input') oninput() {
    this.searchItems();
  }

  ngOnInit() {
    for (let i = 1; i <= 10; i++) {
      this.elements.push({
        id:i.toString(),
        first: 'Wpis' + (Math.floor(Math.random() * i * 10)).toString(),
        last: 'Last' + (Math.floor(Math.random() * i * 10)).toString(),
        handle: 'Handle' + (Math.floor(Math.random() * i * 10)).toString()
      });
    }
    this.mdbTable.setDataSource(this.elements);
    this.previous = this.mdbTable.getDataSource();
  }

  searchItems() {
    const prev = this.mdbTable.getDataSource();
    if (!this.searchText) {
      this.mdbTable.setDataSource(this.previous);
      this.elements = this.mdbTable.getDataSource();
    }
    if (this.searchText) {
      this.elements = this.mdbTable.searchLocalDataByMultipleFields(this.searchText, ['first', 'last']);
      this.mdbTable.setDataSource(prev);
    }
  }
}

Actual behavior

import { AfterViewInit, ChangeDetectorRef, Component, HostListener,
Input, OnInit, ViewChild
   } from '@angular/core';
import { MdbTableDirective, MdbTablePaginationComponent } from 'ng-uikit-pro-standard';

import { ClientsService } from './clients.service';

@Component({
  selector: 'app-clients',
  templateUrl: './clients.component.html',
  styleUrls: ['./clients.component.scss']
})
export class ClientsComponent implements OnInit, AfterViewInit {

  @ViewChild(MdbTablePaginationComponent, { static: true }) mdbTablePagination: MdbTablePaginationComponent;
  @ViewChild(MdbTableDirective, { static: true }) mdbTable: MdbTableDirective;

  @HostListener('input') oninput() {
    this.buscaPDV();
  }  
  ngOnInit():void {}

  ngAfterViewInit(): void { 
    this.getClientsPaginate(this.pages);
    this.mdbTable.setDataSource(this.tableData);
    this.previous = this.mdbTable.getDataSource();
  }

  buscaPDV(): void {
    console.log('SearchPdv: ',this.searchPDV)
    const prev = this.mdbTable.getDataSource();
    if (!this.searchPDV) {
      this.mdbTable.setDataSource(this.previous);
      this.tableData = this.mdbTable.getDataSource();
    }
    if (this.searchPDV) {
      this.tableData = this.mdbTable.searchLocalDataByMultipleFields(this.searchPDV, ['razaoSocial', 'email']);
      this.mdbTable.setDataSource(prev);
    }
  }    

CoreModule.ts:

import { AccordionModule, BadgeModule, ButtonsModule, CardsModule, CarouselModule, CheckboxModule,    
         ChartsModule, IconsModule, MDBSpinningPreloader, ModalModule, NavbarModule, PopoverModule, 
         SidenavModule, SmoothscrollModule, TableModule, TooltipModule, WavesModule 
        } from 'ng-uikit-pro-standard';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
  ],
  exports: [
    AccordionModule,
    BadgeModule,
    ButtonsModule,     
    BrowserModule,
    BrowserAnimationsModule,
    CardsModule,
    CarouselModule, 
    CheckboxModule,    
    ChartsModule,
    FormsModule,
    HttpClientModule,
    IconsModule,
    ModalModule,    
    NavbarModule,
    PopoverModule,
    TableModule,
    TooltipModule, 
    ReactiveFormsModule,
    SmoothscrollModule,
    SidenavModule,
    WavesModule
  ],
  providers: [MDBSpinningPreloader],  
})
export class CoreModule { }

Resources (screenshots, code snippets etc.) enter image description here


Arkadiusz Idzikowski staff commented 1 year ago

We just tested this directive and could not reproduce such a problem. Which version of Angular and MDB Angular do you use?

Could you please provide some more information about the HTML code (the part when you use the mdbTable directive)? Is the element with the mdbTable rendered on component init?


allancmello pro commented 1 year ago

HI,

  • Angular version 14!

  • Is rendered in ngAfterViewInit

Code bellow:


allancmello pro commented 1 year ago

        <div class="px-3">
        <div class="table-wrapper">
            <table class="table table-striped w-auto scrollY mb-0" mdbTable hover *ngIf="tableData">
                <thead>
                    <tr class="table-info">
                        <th>
                           <a>Seleciona</a> 
                        </th>
                        <th>
                            <a (click)="sortBy('ativo')">
                                Ativo
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th>
                            <a (click)="sortBy('bloqueado')">
                                Bloqueado
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th>
                            <a (click)="sortBy('razaoSocial')">
                                Razão Social
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('cnpj')">
                                Cnpj
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('endereco')">
                                Endereço
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('bairro')">
                                Bairro
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('cidade')">
                                Cidade
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('email')">
                                Email
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a (click)="sortBy('contato')">
                                Contato
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                        <th class="th-lg">
                            <a>
                                Telefone
                                <mdb-icon fas icon="sort" class="ml-1"></mdb-icon>
                            </a>
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr [ngClass]="reg % 2 !== 0 ? 'table-primary' : ''" *ngFor="let row of tableData; let reg = index">
                        <td scope="row">
                            <mdb-checkbox class="checkbox-teal text-center" (change)="onChange($event)" (click)="getCheck(reg)"></mdb-checkbox>
                        </td>
                        <td [ngClass]="!row.ativo ? 'red-text': 'black-text'">
                            <strong>{{ row.ativo | SimNao }}</strong>
                        </td>
                        <td [ngClass]="row.bloqueado ? 'amber-text': 'black-text'">
                            <strong>{{ row.bloqueado | SimNao }}</strong>
                        </td>
                        <td >{{ row.razaoSocial }}</td>
                        <td>{{ row.cnpj | cpfcnpj }}</td>
                        <td>{{ row.endereco +", "+ row.numero }} {{ row.complemento | nullToEmpty }}</td>
                        <td>{{ row.bairro }}</td>
                        <td>{{ row.cidade }}</td>
                        <td>{{ row.email }}</td>
                        <td>{{ row.contato }}</td>
                        <td>{{ row.telefone }}</td>
                    </tr>
                </tbody>
            </table>
        </div>

allancmello pro answered 1 year ago


No erro in the console. Value of searchPDV is the value typed.

After typed the array always return empty.

Remember, the value in the mdbTable is False and the search is multiple fields, see image two, line 306:

@ViewChild(MdbTableDirective, { static: false }) mdbTable: MdbTableDirective;

Code HTML:

Code Typescript

Return console searchPDV

Initialization



When you use *ngIf directive on the element with mdbTable, you need to use { static: false } to get access to the table methods in ngAfterViewInit hook. Otherwise, Angular won't be able to find the MdbTableDirective.


allancmello pro commented 1 year ago

Ok Arkadiusz, I try it.


allancmello pro commented 1 year ago

The error for setDataSource its Ok.

But, the searchLocalDataByMultipleFields function does not work.

This function return a empty array of tableData.

Code:

buscaPDV(): void {

    console.log('SearchPdv: ',this.searchPDV)

    const prev = this.mdbTable.getDataSource();

    if (!this.searchPDV) {

        this.mdbTable.setDataSource(this.previous); 

        this.tableData = this.mdbTable.getDataSource(); 


    }

    if (this.searchPDV) {

        this.tableData = this.mdbTable.searchLocalDataByMultipleFields(             
            this.searchPDV, ['razaoSocial', 'cnpj', 'email', 'cidade', 'uf'] );

         this.mdbTable.setDataSource(prev); 


    }

}

Arkadiusz Idzikowski staff commented 1 year ago

Are there any errors in the console when you try to use the search method? What is the value of searchPDV variable when the component returns an empty array?


allancmello pro commented 1 year ago

Hi, Look the post after this for details about your questions.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • User: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: MDB4 4.3.7
  • Device: Desktop
  • Browser: Chrome
  • OS: Windows
  • Provided sample code: No
  • Provided link: No