Search code examples
angularrxjsobservableangular-routingangular-resolver

Angular resolver is not working. Route never subscribes to the observable returned


I am trying to add a resolver to a route of my angular application.

Following is the resolver.

@Injectable()
export class ItemsResolver implements Resolve<Item[]> {
    constructor(private itemService: ItemsService) {
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item[]> {
        return this.itemService.getAll().pipe(first());
    }
}

Following is the getAll() method in itemService, which the resolver calls to get the observable.

public getAll(): Observable<Item[]> {
    console.log('get all called');
    return new Observable<Item[]>(subscriber => {
        console.log('new subscription for items observable');
        this.db.list<Item>('items')
            .valueChanges()
            .subscribe(entities => {
                const items: Item[] = entities.map(entity => entity != null ? new Item(entity) : null);
                ItemsService.setInstances(items);
                subscriber.next(items);
            }, error => subscriber.error(error));
    });
}

Following is the route definition which uses this resolver.

        {
            path: 'edititem/:id', component: EditItemComponent, data: {title: 'Edit Item', type: 'edit'}, resolve: {
                items: ItemsResolver
            }
        }

When user navigates to the route, app hangs and the navigation doesn't complete. It can be seen that only get all called is logged in the console and new subscription for items observable is not logged. So, it looks like the route doesn't subscribe for the observable returned by the resolver.

What could be the reason for this? How can I troubleshoot this further?

Edit

If I returned a promise instead of an observable, it works properly.

@Injectable()
export class ItemsResolver implements Resolve<Item[]> {
    constructor(private itemService: ItemsService) {
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Item[]> {
        return new Promise<Item[]>((resolve, reject) => this.itemService.getAll().pipe(first()).subscribe(value => resolve(value), error => reject(error)));
    }
}

Solution

  • Found the issue. I had imported Observable as follows (both in item service and resolver).

    import {Observable} from "rxjs/index";
    

    When I changed it to following, it started to work.

    import {Observable} from "rxjs";
    

    The first import was added by Intellij IDEA. Observable was working fine, except for the resolver. It is not clear what is the difference between the two imports.