How to show Angular components based on the value of query string?

angular angular2-routing query-string angular-routing angular5

500 观看

1回复

173 作者的声誉

I'm using the Angular 4/5 currently and let’s say I have 2 components Component 1 and Component 2. Now, I've been given a task that if the URL is http://localhost:4200/?property1=value1, then Component 1 will be displayed and if the URL is http://localhost:4200/?property1=value2, then Component 2 will be displayed.

Since I'm a beginner in Angular, therefore, I'm facing problems in these two tasks.

  1. Finding the values of property1 (i.e. value1 and value 2) from the query string each time.

  2. After finding the value, how to define a logic i.e. which component to show?

Although I find this link, I'm unable to find the logic for using the value to see the component. Please help.

Edit: On working through the @Osman Cea's answer, this is the error I'm getting:

null: ERROR
null: Error: StaticInjectorError[ActivatedRoute]: 
__zone_symbol__currentTask: ZoneTask {_zone: Zone, runCount: 0, _zoneDelegates: null, …}
message: "StaticInjectorError[ActivatedRoute]: 
  StaticInjectorError[ActivatedRoute]: 
    NullInjectorError: No provider for ActivatedRoute!"
ngDebugContext: DebugContext_ {view: Object, nodeIndex: 1, nodeDef: Object, …}
ngErrorLogger: function () { … }
ngTempTokenPath: null
ngTokenPath: Array(1) []
stack: "Error: StaticInjectorError[ActivatedRoute]: 
  StaticInjectorError[ActivatedRoute]: 
    NullInjectorError: No provider for ActivatedRoute!
    at _NullInjector.get (webpack-internal:///../../../core/esm5/core.js:1189:19)
    at resolveToken (webpack-internal:///../../../core/esm5/core.js:1477:24)
    at tryResolveToken (webpack-internal:///../../../core/esm5/core.js:1419:16)
    at StaticInjector.get (webpack-internal:///../../../core/esm5/core.js:1290:20)
    at resolveToken (webpack-internal:///../../../core/esm5/core.js:1477:24)
    at tryResolveToken (webpack-internal:///../../../core/esm5/core.js:1419:16)
    at StaticInjector.get (webpack-internal:///../../../core/esm5/core.js:1290:20)
    at resolveNgModuleDep (webpack-internal:///../../../core/esm5/core.js:11074:25)
    at NgModuleRef_.get (webpack-internal:///../../../core/esm5/core.js:12306:16)
    at resolveDep (webpack-internal:///../../../core/esm5/core.js:12804:45)"
__proto__: Object {constructor: , name: "Error", message: "", …}
null: ERROR CONTEXT
null: DebugContext_ {view: Object, nodeIndex: 1, nodeDef: Object, elDef: Object, elView: Object}
component: null
componentRenderElement: app-root
context: null
elDef: Object {nodeIndex: 0, parent: null, renderParent: null, …}
elOrCompView: Object
elView: Object {def: Object, parent: null, viewContainerParent: null, …}
injector: Injector_
nodeDef: Object {nodeIndex: 1, parent: Object, renderParent: Object, …}
nodeIndex: 1
providerTokens: Array(1)
references: Object
renderNode: app-root
view: Object {def: Object, parent: null, viewContainerParent: null, …}
__proto__: Object {elOrCompView: <accessor>, injector: <accessor>, component: <accessor>, …}
null: Error: StaticInjectorError[ActivatedRoute]:
作者: TheHungryCoder 的来源 发布者: 2017 年 12 月 27 日

回应 1


2

1089 作者的声誉

决定

You can get a reference of your queryParams Observable by injecting the ActivatedRoute in your parent component and subscribing to it. Let's say you have the following app.component.ts:

import { ActivatedRoute } from '@angular/router';
@Component({
  template: `
    <ng-container [ngSwitch]="activeParam">
      <component-one *ngSwitchCase="'value1'"></component-one>
      <component-two *ngSwitchCase="'value2'"></component-two>
    </ng-container>
  `
})
export class AppComponent {
  activeParam: string;

  constructor(private route: ActivatedRoute) {
    this.route.queryParams.subscribe(params => this.activeParam = params.property1)
  }
}

What you get in the params argument is a plain regular object with the following signature { [key: string]: any } where key is the name of the param, and the value... well, the value of the given param. You can get a hold of that value inside the activeParam property and use the ngSwitch directive to decide which component to render.

You could also do this with Observables and the async pipe like this:

import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { pluck } from 'rxjs/operators';
@Component({
  template: `
    <ng-container [ngSwitch]="activeParam$ | async">
      <component-one *ngSwitchCase="'value1'"></component-one>
      <component-two *ngSwitchCase="'value2'"></component-two>
    </ng-container>
  `
})
export class AppComponent {
  activeParam$: Observable<string>;

  constructor(private route: ActivatedRoute) {
    this.activeParam$ = this.route.queryParams.pipe(pluck('property1'))
  }
}

In this case you're extracting the value assigned to the property1 key in the object you get when subscribing to the observable, this way it will safely ignore those queryParams you don't actually need to observe, and the value of the Observable will either be value1 or value2, or whatever it's after the = in your url.

作者: Osman Cea 发布者: 2017 年 12 月 27 日
32x32