Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular queryParamMap is empty, then populated

I have created a new module in my app so I can separate parts that do not have to communicate and created an new.module.ts with its own routing module and components :

new-routing.module.ts:

const exportRoutes: Routes = [
  {
    path: 'export',
    component: ExportsComponent
  }
]

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

new.module.ts:

import { Router } from '@angular/router'
import { BrowserModule } from '@angular/platform-browser'

// Routing Module
import { NewRoutingModule } from './new-routing.module'

@NgModule({
  imports: [..., ExportRoutingModule, ...],
  declarations: [ExportsComponent],
  bootstrap: [ExportsComponent]
})

I have a simple index.html:

<body class="app">
  <router-outlet></router-outlet> // outlet is here because I read that I needed it to be able to use activated route, I actually just want the query params
</body>

and finally, where the problem lies, my component :

export class MyComponent implements OnInit {

constructor(private activatedRoute: ActivatedRoute) {}

ngOnInit() {this.activatedRoute.queryParamMap.subscribe(
(params: ParamMap) => console.log(params) 
// Do stuff with params => error)}

When I navigate to http://localhost:4200/export?firstParam=1.00,2.00,3.00 in my console, the params are logued twice, once empty, once populated as such :

ParamsAsMap {params: {…}}
keys:(...) // empty
params:{} // empty

core.js:3565 Angular is running in the development mode. Call enableProdMode() to enable the production mode.

ParamsAsMap {params: {…}}
keys:Array(3)
params:{firstParam: "1.00,2.00,3.00", secondParam: "bla"}

This cause my component to throw error since I need those params to display my component and the first time they are logued they are empty so :

  • Why are they loggued twice ?
  • Why is my code executed before my params observable has a value ?
  • Could I get rid of the router outlet (which I don't really need since I have no routing involved with this module, I just used it because I read that I couldn't use activatedRoute without it; I just want the query params from my url

Thanks for your help

like image 910
Lakston Avatar asked Nov 22 '17 09:11

Lakston


1 Answers

I'll offer 2 solutions to this problem, first, using the skip operator :

Since Activated Route is a BehaviorSubject so first we'll get an empty value, then the actual queryparams so we can skip the first value :

(note, this solution uses lettable operators, hence the pipe(), if you are not using lettable operators you can just chain it like you would do any other rxjs operators : .skip(1)

export class MyComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() 
    {this.activatedRoute.queryParamMap.pipe(skip(1)).subscribe(
    (params: ParamMap) => console.log(params)}

Second solution, use a regular javascript function to retrieve the params :

ngOnInit() {
  const token = this.getParameterByName('access_token');
  console.log(token);
}

getParameterByName(name: any) {
  let url = window.location.href;
  name = name.replace(/[[]]/g, "\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
  results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/+/g, " "));
}

I'll point you to this stackoverflow answer for the original code

like image 131
Lakston Avatar answered Nov 11 '22 01:11

Lakston