2

I have a problem with Angular2 resolver being instantiated multiple times.

This is my feature module declaration (loaded lazily by the router):

const ROUTES: Route[] = [
    {

        path: '',
        component: ScreenParentComponent,
        children: [
            {
                path: '',
                component: InnerScreenParentComponent,
                children: [
                    {
                        path: '',
                        pathMatch: 'full',
                        redirectTo: 'urlA'
                    },
                    {
                        path: 'urlA',
                        component: ChildComponentA,
                        resolve: [ResolverA, ResolverB]
                    }
                ]
            }
        ]
    }
];

@NgModule({
    providers: [
        ResolverA,
        ResolverB
    ],
    declarations: [
        InnerScreenParentComponent,
        ChildComponentA
    ],
    imports: [
        SharedModule,
        RouterModule.forChild(ROUTES)
    ]
})
export class MyFeatureModule {

}

This is the code for a Resolver in question (let's call it ResolverA):

import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs";
import {AuthHttp} from "angular2-jwt";

@Injectable()
export class ResolverA implements Resolve<IDataDto> {

    private API_URL = '...';
    private _reasons: IDataDto[];

    constructor(private http: AuthHttp) {
        console.log("Resource NEW");
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
        console.log("Resource RESOLVE");
        return this.http.get(this.API_URL)
            .map(result => result.json())
            .do(result => this._reasons = result);
    }

    get reasons(): IDataDto[] {
        return this._reasons;
    }

}

export interface IDataDto {
    reasonCode: string,
    description: string,
    gainLossType: GainLossType

}

export type GainLossType = "GAIN" | "LOSS";

And a component:

// All needed imports   

@Component({
    selector: 'componentA',
    template: require('./componentA.template.html')
})
export class ComponentA implements OnInit {


    constructor(private router: Router,
                private timeResolver: TimeResolver,
                private resolverA: ResolverA,
                private messageService: MessageService) {

    }

    ngOnInit(): void {

        // other UI initialization code

        this.initData();
    }


    private initData() {
        let reasons = this.resolverA.reasons; //UNDEFINED!
        console.log("Reasons:", reasons);
    }    
}

The problem is, that this ResolverA is instantiated two times (and resolved only in one instance). The second instance (that is injected into the component) has unresolved data. In fact, the second instance shouldn't even exist, the resolver should be singleton.

Console output in this case:

Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
Resource NEW
Resource RESOLVE
Resource NEW //THIS SHOULDN'T BE HERE
Reasons: undefined
Reasons: undefined

Works as expected in angular 2.1.2 but not in angular 2.2.4. Typescript version: 2.0.10

Is there something wrong with my code (something that has changed since angular 2.2) or it this to be considered a bug in Angular?

1 Answer 1

3

There is a known issue about providers in lazy loaded modules being instantiated multiple times

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I will revert router to 3.1.1 for the time being.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.