Cannot access AccordionItems after asynchronously loading them

Hello Syncfusion team, 

I am having some issues right now with the Syncfusion angular accordion.
I am dynamically generating accordion items based on a JSON config that I am loading in the ngOnInit method. Here a shortened version of this code:

  <ejs-accordion #acc (expanded)="afterAccordionItemExpansion()" expandMode='Multiple'>
      <e-accordionitems>
        <e-accordionitem #accordionItem expanded='true' *ngFor="let accordionItem of accordion">
          <ng-template #header>
            ...
          </ng-template>
          <ng-template #content>
            ...
          </ng-template>
        </e-accordionitem>
      </e-accordionitems>
  </ejs-accordion>
...
  public accordionany;
...
  ngOnInit() {

    this.dataService.getIDockingComponentConfigById(this.state.id).then((config=> {
        this.componentConfig = config;
        this.accordion = this.componentConfig.componentData.metaData;

        // init
        this.initInLayout(this.componentConfig);
      });
    }
  }

So I am loading my component config in ngOnInit and based on the metaData, I am generating the according amount of accordion items.
But when I do that, the accordion items ignore the expanded='true' statement. 

So I was trying to access the expanded variable by code and created a ViewChild of the accordion thinking I could access its items, but this did not work either. 

To examine this problem, I created a second accordion with the same skeleton and the only difference that instead of using *ngFor="let accordionItem of accordion", I was using *ngFor="let i of [1,2,3]". So no variable that needs to be evaluated asynchronously. 

I logged the accordion items of both my normal accordion and my dummy accordion afterViewInit and after a button press (so the data is definitely loaded): 
And as a result, I recognized that the accordion items are not having the type AccordionItem and I was only getting TemplateRefs (picture below).

So my question is: What creates this difference between the accordion representations and why is the expanded-property not set accordingly.  
And finally: is there a way to handle this concrete situation and still access the AccordionItems?  

Thanks in regard
Jonas Czeslik



8 Replies

BS Balasubramanian Sattanathan Syncfusion Team March 16, 2021 09:54 AM UTC

Hi Jonas, 

Greetings from Syncfusion Support. 

We have analyzed your reported scenario at our end and suspect that you could not access the dynamically added accordion items. We have prepared a sample and tried to reproduce the problem in it. But unfortunately, we were unable to reproduce it at our end. In the below sample, we have added accordion items dynamically through a button click. And the item has expanded property in it. After the items added to the accordion, which is accessible and the expanded property also remains the same. 


Kindly refer and follow the above sample, let us know the below details if the problem is not resolved. 
  • Did you add any configurations for accordion items in the expanded event?
  • Could you please share the video demo that illustrates the problem with replication steps?
  • Share an issue reproduced sample(if possible) or try to reproduce the problem in the above sample and share the replication steps.

Regards, 
Balasubramanian S 



JC Jonas Czeslik March 16, 2021 12:38 PM UTC

The problem is that I cannot really create these accordion items in code because their content is way too much to put it in every item. 

In my scenario, I have an accordion (acc) with several accordionItems that are dynamically created in the ngOnInit. In this method, I am getting the metaData that tell me how the accordionItems should be formed =>           So here I create an accordionItem for every item in the dynamically called accordion and based on this accordionItem, I am creating a dynamic content based on a complex html skeleton. 

I changed the stackBlitz example to hopefully clarify the issue. The accordionItem amount is now determined by the result length itself and the title and content HTML here are constant (in my case it would depend on result parameters). The result length is 3, which also reflects in the item length of the accordion, BUT here again these are not saved as AccordionItems and I would not have access on them. Why is that the case? 

https://stackblitz.com/edit/angular-accordion-items-added-dynamically-through-button-mbqamg?file=default.component.ts


BS Balasubramanian Sattanathan Syncfusion Team March 18, 2021 03:27 PM UTC

Hi Jonas, 

Thanks for your patience. 

We have checked your modified sample at our end and let you know that you have assigned the e.result directly to the accordion items when clicking the button. But the e.result has multiple items inside it. So we should map the relevant fields to the accordion header and the content fields like below. So if this.result value got changed dynamically the accordion items also will change the same. 

result; 

public click() { 
  new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) 
    .executeQuery(new Query().range(1, 4)) 
    .then((e: ReturnOption) => { 
      let result: any = e.result; 
      for (let i: number = 0; i < result.length; i++) { 
        this.accordionItems.push({ 
          header: result[i][this.mapping.header], 
          content: result[i][this.mapping.content], 
          expanded: true 
        }); 
     
      this.result = this.accordionItems; 

      console.log(this.result); 
      console.log(this.acrdnInstance); 
      console.log(this.acrdnInstance.items); 
    });
 

Kindly refer and follow the above solution at your end and let us know if this comes close to your requirement. 

Regards, 
Balasubramanian S 



JC Jonas Czeslik March 18, 2021 03:54 PM UTC

Okay, but in this case, my problem would still be the same that I would have to assign a content to any accordion item, which I cannot really do because the template is not accessible in the e.result variable. I would have to fill in the template that is defined in the same html class, but according to some flags that are set in the e.result. How would that be possible? 


JC Jonas Czeslik replied to Balasubramanian Sattanathan March 18, 2021 05:59 PM UTC

Hi Jonas, 

Thanks for your patience. 

We have checked your modified sample at our end and let you know that you have assigned the e.result directly to the accordion items when clicking the button. But the e.result has multiple items inside it. So we should map the relevant fields to the accordion header and the content fields like below. So if this.result value got changed dynamically the accordion items also will change the same. 

result; 

public click() { 
  new DataManager({ url: SERVICE_URI, adaptor: new ODataAdaptor() }) 
    .executeQuery(new Query().range(1, 4)) 
    .then((e: ReturnOption) => { 
      let result: any = e.result; 
      for (let i: number = 0; i < result.length; i++) { 
        this.accordionItems.push({ 
          header: result[i][this.mapping.header], 
          content: result[i][this.mapping.content], 
          expanded: true 
        }); 
     
      this.result = this.accordionItems; 

      console.log(this.result); 
      console.log(this.acrdnInstance); 
      console.log(this.acrdnInstance.items); 
    });
 

Kindly refer and follow the above solution at your end and let us know if this comes close to your requirement. 

Regards, 
Balasubramanian S 


Okay, I guess I understood it now, but I ran into the next problem, which I made visible in the following example: 

https://stackblitz.com/edit/angular-accordion-items-added-dynamically-through-button-ojtiwm?file=default.component.ts

I added a ejs textbox to all of the accordion item contents and created a ViewChildren QueryList of all Textboxes. Also, I added a functionality for expanding and collapsing all accordion items. Now, the problem is that collapsing and expanding all accordion items have an impact on the textbox viewchildren and expands these instead of keeping the same three elements that represent the accordion. Can that be prevented? And shouldnt collapsing and expanding have no impact on the querylist since these elements are not really deleted from the DOM?



BS Balasubramanian Sattanathan Syncfusion Team March 22, 2021 12:42 PM UTC

Hi Jonas, 

Thanks for the reply. 

We have validated your reported scenario at our end and suspect that you might lost the edited value in the textboxes after expanding or collapsing the accordion and render textboxes with initial value when enable the textbox component. Kindly confirm whether you have encountered this problem. If not, provide more details such as issue replication steps in the shared sample or a video demo to validate the issue and provide a prompt solution. 

Regards, 
Balasubramanian S 



JC Jonas Czeslik March 22, 2021 02:44 PM UTC

I found the issue! 
I replaced 1) with 2)

1)
    this.acc.items.forEach((item=> {
      item.expanded = false;
    });

2)
    for (var i = 0i < this.acc.items.lengthi++) {
      this.acc.expandItem(falsei);
    }

This lead to the QueryList not having duplicate entries and solved my problem.




NR Nevitha Ravi Syncfusion Team March 23, 2021 04:54 AM UTC

Hi Jonas, 

Thanks for your update. 

We are happy that your issue is resolved at your end. Please get back to us if you need any further assistance. 

Regards, 
Nevitha 


Loader.
Up arrow icon