Export to Excel with async data

5 posts, 1 answers
  1. Randy
    Randy avatar
    23 posts
    Member since:
    Sep 2012

    Posted 09 Jan Link to this post

    Hi,

    I'm referencing https://www.telerik.com/kendo-angular-ui/components/excelexport/how-to/export-to-separate-sheets/ to do Excel export with *ngFor option, but the difference is that my data comes from a service instead of static client data. When calling 'this.excelExportComponents.first.save(workbooks[0]);' in the subscribe of the service call, I got below error:

    core.js:6014 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'save' of undefined
    TypeError: Cannot read property 'save' of undefined
        at management-view.component.ts:175
        at ZoneDelegate.invoke (zone-evergreen.js:359)
        at Object.onInvoke (core.js:39699)
        at ZoneDelegate.invoke (zone-evergreen.js:358)
        at Zone.run (zone-evergreen.js:124)
        at zone-evergreen.js:855
        at ZoneDelegate.invokeTask (zone-evergreen.js:391)
        at Object.onInvokeTask (core.js:39680)
        at ZoneDelegate.invokeTask (zone-evergreen.js:390)
        at Zone.runTask (zone-evergreen.js:168)
        at resolvePromise (zone-evergreen.js:797)
        at zone-evergreen.js:862
        at ZoneDelegate.invokeTask (zone-evergreen.js:391)
        at Object.onInvokeTask (core.js:39680)
        at ZoneDelegate.invokeTask (zone-evergreen.js:390)
        at Zone.runTask (zone-evergreen.js:168)
        at drainMicroTaskQueue (zone-evergreen.js:559)
        at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
        at invokeTask (zone-evergreen.js:1603)
        at XMLHttpRequest.globalZoneAwareCallback (zone-evergreen.js:1640)

    I guess this.excelExportComponents.first is not ready yet in the sevice call subscribe and I should call the 'save' method at some point after the binding finished. After some experiment I ended up using a flag set to true after service call and in AfterViewChecked hook checking if the flag is true then do the concat and save, then reset the flag. This seems to work but seems not so ideal, as AfterViewChecked is quite frequently called. If there's better way do export async data?

    Thanks.

  2. Svetlin
    Admin
    Svetlin avatar
    382 posts

    Posted 10 Jan Link to this post

    Hi Randy,

    Indeed, your observations make sense. From the provided error it seems that this.excelExportComponents.first is undefined at the moment of calling its save() method.

    What else could be done is to call the save() method within the subscribe of the service only when the data has successfully arrived.

    Another approach would be to use the ngAfterViewInit hook instead of the afterViewChecked.

    I hope this helps. Please let us know in case further assistance is required for this case.

    Regards,
    Svetlin
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Randy
    Randy avatar
    23 posts
    Member since:
    Sep 2012

    Posted 10 Jan in reply to Svetlin Link to this post

    Hi Svetlin,

    Thank you for replying.

    The first approach, calling the save() method within the subscribe of the service was my first attempt, and that's when the error occurs. Here's the sample code (this.results is bind to the excel export component):

    this.someService.someCall().subscribe(
       result => {
          this.results = result.value.map(v => v.Items);
          const options = this.excelExportComponents
            .toArray()
            .map(c => c.workbookOptions());
          Promise.all(options).then(workbooks => {
            for (let i = 0; i < options.length - 1; i++) {
              workbooks[0].sheets = workbooks[0].sheets.concat(
                workbooks[i + 1].sheets
              );
            }
            this.excelExportComponents.first.save(workbooks[0]);
          });
    });

     

    I did tried 2nd approach also, but seems ngAfterViewInit hook is not called after sevice called and this.results rebinding. Guess no repaint is triggered.

  4. Answer
    Svetlin
    Admin
    Svetlin avatar
    382 posts

    Posted 13 Jan Link to this post

    Hi Randy,

    In order to ensure that the this.excelExportComponents.first is initialized at the time of calling its save() method it can be added within a setTimeout() function as follows:

    this.someService.someCall().subscribe(
       result => {
          this.results = result.value.map(v => v.Items);
          const options = this.excelExportComponents
            .toArray()
            .map(c => c.workbookOptions());
          Promise.all(options).then(workbooks => {
            for (let i = 0; i < options.length - 1; i++) {
              workbooks[0].sheets = workbooks[0].sheets.concat(
                workbooks[i + 1].sheets
              );
            }
           setTimeout(()=>{
               this.excelExportComponents.first.save(workbooks[0]);
            })
          });
    });

    Also, the logic within the subscribe of the Observable can be implemented only if there is some result:

    this.someService.someCall().subscribe(
       result => {
          if(result.value.length > 0){
       this.results = result.value.map(v => v.Items);
          const options = this.excelExportComponents
            .toArray()
            .map(c => c.workbookOptions());
          Promise.all(options).then(workbooks => {
            for (let i = 0; i < options.length - 1; i++) {
              workbooks[0].sheets = workbooks[0].sheets.concat(
                workbooks[i + 1].sheets
              );
            }
            this.excelExportComponents.first.save(workbooks[0]);
         }
        
          });
    });

    Please check these suggestions and let us know in case further assistance is required. Thank you in advance.

    Regards,
    Svetlin
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  5. Randy
    Randy avatar
    23 posts
    Member since:
    Sep 2012

    Posted 13 Jan in reply to Svetlin Link to this post

    Hi Svetlin,

    Both suggestions worked perfectly. Thank you for the great support.

Back to Top