How to get QueryParam in factory provider (Angular4)

1.4k Views Asked by At

I want to provide a constant in my application basing on QueryParam from url.

localhost:4200?flag=true

In my module providers I added

{ provide: FLAG, useFactory: FlagFactory, deps: [...] }

So I am interested if there is a way how to do it without parsing url manually

function FlagFactory() {
  return location.search.includes('flag');
}
2

There are 2 best solutions below

4
On

What about using Angular Router?

The router tracks query parameters, so they should be available on you initial route '/'

your root component could have a route that allows this

constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
       this.flag = params['flag']; 

    });
  }
0
On

I was able to do this by using Angular's resolve. Resolve allows you to access the route and query params BEFORE your route component is loaded.

In your case, I would create a resolver class that looks something like this:

@Injectable()
export class FlagRouteResolver implements Resolve<any> {
    constructor(private flagService: FlagService) {}

    resolve(route: ActivatedRouteSnapshot) {
        this.flagService.isFlagged = route.queryParamMap.get('flag');

        // Need to return an observable for all resolve() methods
        return Observable.of(null);
    }
}

And your AppModule should look something like this:

@NgModule({
    imports: [
        RouterModule.forRoot([{
            path: 'flagRoute',
            component: FlagComponent,
            resolve: { test: FlagRouteResolver }
        }]),
    ],
    providers: [
        FlagService,
        FlagRouteResolver
    ],
    declarations: [
        FlagComponent
    ]
})

So now, within your route component, you should be able to access that value immediately in the constructor like so:

constructor(private flagService: FlagService) {
    this.isFlagged = this.flagService.isFlagged;
}

But if you'd still like to inject it, you can also do it like so:

providers: [{
    provide: FLAG,
    useFactory: (flagService: FlagService) => {
        return this.flagService.isFlagged;
    },
    deps: [FlagService]
}]