0

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]:
KhiladiBhaiyya
  • 633
  • 1
  • 14
  • 43

1 Answers1

2

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
  • 1,467
  • 9
  • 18
  • Both of these methods didn't work for me as I got the `Error: StaticInjectorError[ActivatedRoute]` whenever I tried to opened the link http://localhost:4200/?property1=value1 or the one with the value2. How to fix this error? – KhiladiBhaiyya Dec 28 '17 at 04:56
  • I've posted the complete error message trace in the question. Please see it. – KhiladiBhaiyya Dec 28 '17 at 05:12
  • 1
    I guess this is because you have to import the `RouterModule` into your main `AppModule` – Osman Cea Dec 28 '17 at 08:21
  • I imported the RouterModule in my AppModule as `RouterModule.forRoot(routes)` and the code was working successfully. But one thing which I can't understand is that why it is working even on providing the empty array routes as `const routes: Routes = [ ];`. Can you please clear this doubt of mine? – KhiladiBhaiyya Dec 29 '17 at 06:33