0
votes

I know am not the first to ask this ,Here I am working in an Angular 5 application in this I need to open an accordion programmatically.

Here everything is fine and working as I expected in stackblitz but not in my project .

I have verified all the script reference and their alignments of both projects.I couldn't find any difference .

stackblitz :

https://stackblitz.com/edit/angular-bootstrap-carousel-dynamic2-zqoeiw?file=index.html

Error:

ERROR TypeError: Cannot read property 'nativeElement' of undefined
    at eval (eval at ../../../../../src/app/Components/List And Grid View Components/common/common.component.ts (main.bundle.js:28), <anonymous>:56:20)
    at SafeSubscriber.schedulerFn [as _next] (core.js:4331)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
    at SafeSubscriber.next (Subscriber.js:187)
    at Subscriber._next (Subscriber.js:128)
    at Subscriber.next (Subscriber.js:92)
    at EventEmitter.Subject.next (Subject.js:56)
    at EventEmitter.emit (core.js:4299)
    at QueryList.notifyOnChanges (core.js:6439)
    at checkAndUpdateQuery (core.js:12833)

app.componant.html

<div class="accordion col-sm-12" id="accordion1" *ngFor='let data of dropdownData; let i=index'>
    <div class="accordion-group">

        <div class="accordion-heading">
            <a class="accordion-toggle h6" data-toggle="collapse" routerLink="/two/{{i}}" data-parent="#accordion1" href="#collapseTwo + i">
                {{data?.CAMD_ENTITY_DESC}}
            </a>
        </div>
    </div>
</div>

app.module.ts

const appRoutes: Routes = [
      {path:'one',component:OneComponent},
       {path:'two/:id',component:TwoComponent}]

common.component.html

<div class="accordion col-sm-12" id="accordion1" *ngFor='let data of dropdownData; let i=index'>
        <div class="accordion-group">

          <div class="accordion-heading">
            <a class="accordion-toggle h6" data-toggle="collapse"    data-parent="#accordion1" href="#collapseTwo + i" #accordian>
              {{data?.CAMD_ENTITY_DESC}}
            </a>
          </div>
//other codes
</div>
</div>

common.component.ts

import { Component, OnInit, ViewChildren, QueryList, AfterViewInit, ElementRef } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
import { CartdataService } from '../../../services/cartdata.service';

declare var $: any;

@Component({
  selector: 'app-common',
  templateUrl: './common.component.html',
  styleUrls: ['./common.component.css']
})

export class CommonComponent implements OnInit, AfterViewInit {

  id: string;
  dropdownData: any;

  @ViewChildren('accordian') components: QueryList<ElementRef>;
  constructor(private route: ActivatedRoute, private router: Router, private CartdataService: CartdataService) { }

  ngOnInit() {

    this.CartdataService.get_Product_Categories().subscribe(
      data => {
        this.dropdownData = data;
      });
    this.id = this.route.snapshot.paramMap.get('id');
  }


  ngAfterViewInit() {
    this.components.changes.subscribe(() => {
      let elem = this.components.toArray()[this.id];
      $(elem.nativeElement).trigger("click");
    });
  }
}

index.html

<body>

  <app-root></app-root>
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
    crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
    crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
    crossorigin="anonymous"></script>


</body>

angular-cli.json

"styles": [
        "styles.css"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.min.js",
    "../node_modules/bootstrap/dist/js/bootstrap.min.js"
      ]

package.json

"dependencies": {
    "@agm/core": "^1.0.0-beta.2",
    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "angular-web-storage": "^2.0.0",
    "angular-webstorage-service": "^1.0.2",
    "auth0-js": "^9.3.1",
    "bootstrap": "^4.1.1",
    "core-js": "^2.4.1",
    "dateformat": "^3.0.3",
    "jquery": "^3.3.1",
    "jquery.js": "0.0.2-security",
    "popper.js": "^1.14.3",
    "public-ip": "^2.4.0",
    "rxjs": "^5.5.6",
    "zone.js": "^0.8.19"
  }

can anyone tell me where I did the mistakes and how to solve these error.

1
perhaps there is a delay in receiving data in your project? are you receiving it correctly? - Suraj Rao
In my real project there is no delay it's binding correctly @SurajRao - Nikson
what is the output of console.log(elem)? - Saksham Gupta
nativeElement : a.accordion-toggle.h6 I got this in console @Saksham Gupta - Nikson

1 Answers

0
votes

It's because there is no element that @ViewChildren('accordian') can find. No element in the view has a reference named accordian. To put a reference, you do it like this:

<div #reference></div>

In your case,

<div #accordian></div>

EDIT

The culprit is then your business logic.

let elem = this.components.toArray()[this.id];

This is where you get undefined. Try doing

console.log(this.components.toArray())

to see what is queries. Revise your logic. Everything Angular-related is working here.