[ANGULAR] Uncaught in promise error when navigating while loading

Our pure JavaScript Scheduler component


Post Reply
User avatar
jmeire
Posts: 30
Joined: Tue Jan 28, 2020 4:04 pm

[ANGULAR] Uncaught in promise error when navigating while loading

Post by jmeire »

Hi

I discovered the following behaviour:
When the scheduler is loaded and you navigate to another component, everything is fine.
But when you navigate while the scheduler is still fetching data an error occurs.

Example gif:
hLyy8HcJ5q.gif
hLyy8HcJ5q.gif (207.36 KiB) Viewed 273 times

Full error:

Code: Select all

Error: Uncaught (in promise): TypeError: _0x259982.through[_0x4dce(...)] is not a function
TypeError: _0x259982.through[_0x4dce(...)] is not a function
    at scheduler.module.js:9
    at Array.forEach (<anonymous>)
    at ResourceStore.trigger (scheduler.module.js:9)
    at scheduler.module.js:21
    at ZoneDelegate.invoke (zone-evergreen.js:365)
    at Object.onInvoke (core.js:40794)
    at ZoneDelegate.invoke (zone-evergreen.js:364)
    at Zone.run (zone-evergreen.js:124)
    at zone-evergreen.js:851
    at ZoneDelegate.invokeTask (zone-evergreen.js:400)
    at resolvePromise (zone-evergreen.js:793)
    at zone-evergreen.js:858
    at ZoneDelegate.invokeTask (zone-evergreen.js:400)
    at Object.onInvokeTask (core.js:40772)
    at ZoneDelegate.invokeTask (zone-evergreen.js:399)
    at Zone.runTask (zone-evergreen.js:168)
    at drainMicroTaskQueue (zone-evergreen.js:570)
    at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:485)
    at invokeTask (zone-evergreen.js:1596)
    at XMLHttpRequest.globalZoneAwareCallback (zone-evergreen.js:1633)

Example project:
unCaughtInPromiseError.zip
(17.36 MiB) Downloaded 8 times
How can I handle or prevent this error?

Kind regards
jmeire

User avatar
saki
Core Developer
Core Developer
Posts: 594
Joined: Thu Mar 30, 2017 9:32 am

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by saki »

If you use Angular router with default config then the scheduler is destroyed and then re-created. It looks like some requests are not aborted properly. It may be a bug but we will first analyze your code.

If you do not want to destroy and re-create scheduler on each navigation then you can use our approach from our routing example where we have custom routing strategy implemented.

User avatar
saki
Core Developer
Core Developer
Posts: 594
Joined: Thu Mar 30, 2017 9:32 am

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by saki »

It doesn't look like a bug in scheduler. The requests are sent by your code so you need to abort them before destroying scheduler page. Your bryntum.component should probably implement onDestroy method and there you should abort all pending requests.

User avatar
jmeire
Posts: 30
Joined: Tue Jan 28, 2020 4:04 pm

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by jmeire »

Okay, thanks for analyzing this!

The code that is used to fetch the data with the AjaxHelperOverride was based on this topic a couple of weeks ago:
viewtopic.php?f=44&t=13217&p=68831#p68831

Now I tried to call a couple of things in the ngOnDestroy of my component but none of it seems to prevent the error:
I tried:
scheduler.destroy();
scheduler.ngOnDestroy()
scheduler.resourceStrore.destroy()

How can I abort these requests before destroying the component?
It would be very usefull if this could be automatically destroyed/aborted when destroying the component where the scheduler is used.

User avatar
mats
Core Developer
Core Developer
Posts: 15914
Joined: Sat Dec 19, 2009 11:41 pm
Location: Sweden
Contact:

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by mats »

Can you reproduce this on our vanilla JS examples? Any step by step for us to reproduce it locally?
Tired of debugging javascript errors in web applications? Try our new error logging service RootCause, or read more on the Sencha blog

@bryntum
Facebook
API documentation

User avatar
jmeire
Posts: 30
Joined: Tue Jan 28, 2020 4:04 pm

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by jmeire »

Hi

The issue is triggered when clicking for example on a routerLink while the scheduler is still loading.
So i guess the scheduler is not correctly destroyed which is difficult to implement in a vanilla js example.
It also might be something in the resource store that is not correctly destroyed.

But i again added a zip with all unnecessary code removed.
destroyIssue.zip
(17.36 MiB) Downloaded 6 times

Here is what I did to reproduce it step by step:
- Add bry scheduler component
- Init all its needed properties
- Init the resourceStore with autoLoad true and a read url
- Add an AjaxHelperOverride as described in this topic:
viewtopic.php?f=44&t=13217&p=68870&hilit=load+method+call+starts#p68870
- Add example of promise inside the override (this will be an api call in real world example)
- Add settimeout to mock time of call duration (time that scheduler is in loading state)
- When navigating (to trigger destroy) while the scheduler is still loading, this triggers the error.

As you will see in the example zip, there is a catch on every promise with a log, but none is triggered.

I think, when leaving the component/destroying the component, this should all be handled automatically and I should not have to worry about this behavior.
If I have to do something extra to clean this up in the onDestroy method, that's fine but then I would like to know what.

Thanks in advance for looking into this!

Kind regards
jmeire

User avatar
saki
Core Developer
Core Developer
Posts: 594
Joined: Thu Mar 30, 2017 9:32 am

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by saki »

I made some tests and I found the following sequence of events:
  1. load starts, promises unresolved (yet) Ajax requests pending
  2. navigation occurs
  3. scheduler is destroyed in ngOnDestroy of the wrapper (SchedulerComponent)
  4. response from the server arrives
  5. the scheduler code tries to run various updates with new data on destroyed scheduler
  6. that results in the problem
Now, the solution is to cancel/abort all pending requests before the scheduler is destroyed. I was trying to do it but your requests are wrapped in AjaxHelper so not easily accessible from your component.

Anyway, the code could be as follows:

Code: Select all

  private cleanupSub:Subscription;
  ngOnInit() {
    const cleanup = (e:NavigationStart) => {
      if(e instanceof NavigationStart ) {
        console.log('aborting pending requests');
        // cancel/abort all pending requests here
      }
    };
    this.cleanupSub = this.router.events.subscribe(cleanup);
  }
  ngOnDestroy() {
    if(this.cleanupSub) {
      this.cleanupSub.unsubscribe();
    }
  }
NavigationStart and Subscribe classes must be imported and router injected:

Code: Select all

import { Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs';

// ...

constructor(private router:Router) {
    // the rest of constructor's code
}

User avatar
jmeire
Posts: 30
Joined: Tue Jan 28, 2020 4:04 pm

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by jmeire »

Hi

Thanks for looking into this.

I currently fixed it like this:
in constructor:

Code: Select all

this.destroy$ = new Subject();
(window as any).planningDestroy = this.destroy$;
on destroy:

Code: Select all

public ngOnDestroy(): void {
	this.destroy$.next();
	this.destroy$.complete();
}
And in the AjaxHelperOverride we use a takeUntil of (window as any).planningDestroy on a subscription of a service function, that does an api call.
When the component is destroyed the subscribe body will never be executed.

But still it feels weird to do things like that.
I would like to get a solution that is more 'clean' if possible, without the window object.

Thanks for the help so far!

Kind regards
jmeire

User avatar
saki
Core Developer
Core Developer
Posts: 594
Joined: Thu Mar 30, 2017 9:32 am

Re: [ANGULAR] Uncaught in promise error when navigating while loading

Post by saki »

If you can live with out crudManager you shouldn't need to do this handling. Crud manager knows about requests it sends so it can abort them and uninstall all listeners on destroy.

If you create some async tasks that use scheduler outside of scheduler and scheduler doesn't know about them then you have to take care about the proper destroy process.

Post Reply