Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmptyError: no elements in sequence

I'm upgrading my Angular2 app from 2.0.0 to 2.3.0, and I'm running into the following error. Any ideas as to why? I saw this other post (Angular 2.0.1 Router EmptyError: no elements in sequence), but after trying this, the issue still remains. What causes this error?

Error: Uncaught (in promise): EmptyError: no elements in sequence Error: no elements in sequence     at EmptyError.ZoneAwareError (zone.js:672)     at new EmptyError (EmptyError.ts:13)     at FirstSubscriber._complete (first.ts:161)     at FirstSubscriber.Subscriber.complete (Subscriber.ts:122)     at Subject._subscribe (Subject.ts:109)     at Subject.Observable.subscribe (Observable.ts:98)     at Observable._subscribe (Observable.ts:158)     at Observable.subscribe (Observable.ts:98)     at Observable._subscribe (Observable.ts:158)     at FirstOperator.call (first.ts:82)     at Observable.subscribe (Observable.ts:96)     at Object.subscribeToResult (subscribeToResult.ts:32)     at MergeAllSubscriber._next (mergeAll.ts:82)     at MergeAllSubscriber.Subscriber.next (Subscriber.ts:95)     at MapSubscriber._next (map.ts:80)     at resolvePromise (zone.js:475) [angular]     at resolvePromise (zone.js:460) [angular]     at /libs/zone.js/dist/zone.js:509:17 [angular]     at Object.onInvokeTask (core.umd.min.js:32) [angular]     at ZoneDelegate.invokeTask (zone.js:261) [angular]     at Zone.runTask (zone.js:151) [<root> => angular]     at drainMicroTaskQueue (zone.js:405) [<root>]     at ZoneTask.invoke (zone.js:336) [<root>]ErrorHandler.handleError @ core.umd.min.js:31next @ core.umd.min.js:32generatorOrNext.object.schedulerFn @ core.umd.min.js:32SafeSubscriber.__tryOrUnsub @ Subscriber.ts:238SafeSubscriber.next @ Subscriber.ts:190Subscriber._next @ Subscriber.ts:135Subscriber.next @ Subscriber.ts:95Subject.next @ Subject.ts:61EventEmitter.emit @ core.umd.min.js:32NgZone.triggerError @ core.umd.min.js:32onHandleError @ core.umd.min.js:32ZoneDelegate.handleError @ zone.js:233Zone.runGuarded @ zone.js:129_loop_1 @ zone.js:416drainMicroTaskQueue @ zone.js:425ZoneTask.invoke @ zone.js:336 

I've also noticed that a NavigationError object is thrown when I try to change to a route that uses Guards. But only the error above is what is shown in the console.

NavigationError {id: 2, url: "/home", error: EmptyError}

I'm kind of at a loss and would appreciate any help.

like image 442
hartpdx Avatar asked Dec 13 '16 22:12

hartpdx


2 Answers

This error happens when using RxJS 5.5.3 with angular (version 4/5), so just skip RxJS 5.5.3, and use RxJS 5.5.4 by adding "rxjs": "^5.5.4" to your project package.json.


Before RxJS 5.5.4 came out answer: (old, don't do this)

  • Lock version 5.5.2 RxJS on package.json source
  • add pathMatch: 'full' on empty paths source

It looks like this is an RxJS issue which should be patched pretty soon. source

like image 138
golfadas Avatar answered Sep 28 '22 10:09

golfadas


In my case I've got those errors when I used first() in an Observable that had a takeUntil() emitted before first().

Example:

let test$ = new ReplaySubject(1); let testAux$ = new ReplaySubject(1); let test2$ = test$.asObservable().takeUntil(testAux$.asObservable()); test2$.first().subscribe(() => console.log('first!')); testAux$.next(null); 

It was hard to discover the problem because I returned an observable with takeUntil() in a service that was used by a different class (in a different file) that called first(), and the error was received during page navigation (because takeUntil() received an observable that emitted when the previous page was destroyed), and it appeared as the problem was in the navigation itself.

The weirdest thing is that the error happens when the next() is called, and not in the 2nd argument of subscribe(), causing the navigation process itself to fail. I don't know if this feature was chosen by the rxjs team to behave this way, because it makes much more difficult to isolate the problem, and, the main problem, the producer receives an error because of something done by a consumer, which seems as a bad design to me.

According to this comment:

.first() will emit exactly one item or throw an error[...] If you would like to get at most one item from the observable, use .take(1).

Update (2020-08-31)

It seems that the error can actually be handled by including a 2nd argument to receive errors in the subscription, like in the following case:

const test$ = new ReplaySubject(1); const testAux$ = new ReplaySubject(1); const test2$ = test$.asObservable().takeUntil(testAux$.asObservable()); test2$.first().subscribe(() => console.log('first!'), () => console.log('first error')); testAux$.subscribe(() => console.log('another'), () => console.log('another error')); console.log('1'); testAux$.next(null); console.log('2'); 

That logs:

1 first error another 2 

(in this case you wouldn't see the No elements in sequence error)

But if you want to receive at most 1 item (but it would still be fine to receive none), then take(1) would still be the better approach, and it is what I would recommend by default, instead of first().

like image 38
Lucas Basquerotto Avatar answered Sep 28 '22 09:09

Lucas Basquerotto