Búsqueda de sitios web

typescript - Angular Resolver ERROR Error: No capturado (en promesa): TypeError: resolver no es una función


Tengo un resolve que obtiene datos de una API y un servicio que depende de ese resolve. El servicio que depende del resolve proporcionará secciones de datos a múltiples componentes y solo se espera que se ejecute una vez cuando se cargue la página. Aquí está el código relevante (importaciones y algunas anotaciones omitidas):

detalles-del-producto.servicio.ts

@Injectable()
export class ProductDetailsService {
    private productDetails: ProductDetails;

    constructor(route: ActivatedRoute) {
        this.productDetails = route.snapshot.data['product'];
    }

    public getProductDetails(): ProductDetails {
        return this.productDetails;
    }
}

detalles-del-producto.resolver.ts

@Injectable()
export class ProductDetailsResolve implements Resolve<ProductDetails> {

    constructor(private httpService: HttpService) { }

    resolve(route: ActivatedRouteSnapshot): Observable<ProductDetails> {
        return this.httpService.getProductDetails(route.params['id']);
    }

}

app-routing.module.ts

const routes: Routes = [
    { path: 'main/:id', component: MainComponent, resolve: { product: ProductDetailsService } },
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

algun.componente.ts

export class SomeComponent {
    public value: number = 0;

    constructor(private productDetailsService: ProductDetailsService) {
        this.value = productDetailsService.getProductDetails().value;
    }

}

Cuando ejecuto la aplicación, recibo este error:

core.es5.js:1020 ERROR Error: Uncaught (in promise): TypeError: resolver is not a function
TypeError: resolver is not a function
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.getResolver (router.es5.js:4559)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.resolveNode (router.es5.js:4537)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.runResolve (router.es5.js:4518)
    at MergeMapSubscriber.project (router.es5.js:4285)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:120)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:110)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at ArrayObservable.webpackJsonp.../../../../rxjs/observable/ArrayObservable.js.ArrayObservable._subscribe (ArrayObservable.js:114)
    at ArrayObservable.webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe (Observable.js:171)
    at ArrayObservable.webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe (Observable.js:159)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.getResolver (router.es5.js:4559)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.resolveNode (router.es5.js:4537)
    at PreActivation.webpackJsonp.../../../router/@angular/router.es5.js.PreActivation.runResolve (router.es5.js:4518)
    at MergeMapSubscriber.project (router.es5.js:4285)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:120)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/operator/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:110)
    at MergeMapSubscriber.webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
    at ArrayObservable.webpackJsonp.../../../../rxjs/observable/ArrayObservable.js.ArrayObservable._subscribe (ArrayObservable.js:114)
    at ArrayObservable.webpackJsonp.../../../../rxjs/Observable.js.Observable._trySubscribe (Observable.js:171)
    at ArrayObservable.webpackJsonp.../../../../rxjs/Observable.js.Observable.subscribe (Observable.js:159)
    at resolvePromise (zone.js:795)
    at resolvePromise (zone.js:766)
    at zone.js:844
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.es5.js:3881)
    at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
    at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at <anonymous>

La investigación sobre este error no me ha dado ninguna pista, y no puedo pensar en ninguna razón por la cual el resolve no se reconoce como una función. ¿Hay algo que me esté perdiendo aquí?

Respuesta #1

Recibí este error cuando accidentalmente pasé un Guard como un resolvedor en la configuración de mi ruta:

resolve: { data: MyGuardService }

Así que verifica que no hayas pasado accidentalmente la clase incorrecta. Por ejemplo, si deseas un guardia canActivate, el código se vería así en su lugar:

canActivate: [ MyGuardService ]

Respuesta #2

Recibí este error en Angular 8 porque olvidé implementar la interfaz Resolve<T> en mi clase resolver. Es decir, tuve que cambiar:

@Injectable({
    providedIn: 'root'
}
export class FooResolverService {
    // ...
}

a

@Injectable({
    providedIn: 'root'
}
export class FooResolverService implements Resolve<Foo> {
    // ...
}

Artículos relacionados