42

I am working on this angular2 project in which I am using ROUTER_DIRECTIVES to navigate from one component to other.

There are 2 components. i.e. PagesComponent & DesignerComponent.

I want to navigate from PagesComponent to DesignerComponent.

So far its routing correctly but I needed to pass page Object so designer can load that page object in itself.

I tried using RouteParams But its getting page object undefined.

below is my code:

pages.component.ts

import {Component, OnInit ,Input} from 'angular2/core';
import { GlobalObjectsService} from './../../shared/services/global/global.objects.service';
import { ROUTER_DIRECTIVES, RouteConfig } from 'angular2/router';
import { DesignerComponent } from './../../designer/designer.component';
import {RouteParams} from 'angular2/router';

@Component({
    selector: 'pages',    
    directives:[ROUTER_DIRECTIVES,],
    templateUrl: 'app/project-manager/pages/pages.component.html'
})
@RouteConfig([
  { path: '/',name: 'Designer',component: DesignerComponent }      
])

export class PagesComponent implements OnInit {
@Input() pages:any;
public selectedWorkspace:any;    
constructor(private globalObjectsService:GlobalObjectsService) {
    this.selectedWorkspace=this.globalObjectsService.selectedWorkspace;                    
}
ngOnInit() { }   
}

In the html, I am doing following:

<scrollable height="300" class="list-group" style="overflow-y: auto; width: auto; height: 200px;" *ngFor="#page of pages">
    {{page.name}}<a [routerLink]="['Designer',{page: page}]" title="Page Designer"><i class="fa fa-edit"></i></a>
</scrollable>

In the DesignerComponent constructor I have done the following:

constructor(params: RouteParams) {
    this.page = params.get('page');
    console.log(this.page);//undefined
}

So far its routing correctly to designer, but when I am trying to access page Object in designer then its showing undefined. Any solutions?

Bhushan Gadekar
  • 13,485
  • 21
  • 82
  • 131
  • 5
    `ROUTER_DIRECTIVES` sound like you're using an Angular version from the Dark Ages ;-) – Günter Zöchbauer Feb 02 '17 at 07:56
  • 1
    You can also summon this kind of "satan gimmick": `this.router['arbitraryData'] = data` before navigating and `let arbitraryData = this.router['arbitraryData']` in the final navigation target. I'll leave this here in case I forget and end up finding this page again, just in case – Felype Sep 20 '18 at 17:37

4 Answers4

20

You can't pass objects using router params, only strings because it needs to be reflected in the URL. It would be probably a better approach to use a shared service to pass data around between routed components anyway.

The old router allows to pass data but the new (RC.1) router doesn't yet.

Update

data was re-introduced in RC.4 How do I pass data in Angular 2 components while using Routing?

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • so what can be done in current scenario looking at this project? – Bhushan Gadekar May 11 '16 at 09:11
  • You provide a service at the parent component and inject it in both routed components. When you set a property from one component, the other can read the property. https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service – Günter Zöchbauer May 11 '16 at 09:13
  • I have used that approach for different purpose. I was thinking if I can pass page_id as a string then also its fine. but its getting page_id as a null too. – Bhushan Gadekar May 11 '16 at 09:16
  • If it's a string it should work. A plunker would be nice to debug the issue. – Günter Zöchbauer May 11 '16 at 09:18
19

It changes in angular 2.1.0

In something.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BlogComponent } from './blog.component';
import { AddComponent } from './add/add.component';
import { EditComponent } from './edit/edit.component';
import { RouterModule } from '@angular/router';
import { MaterialModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
const routes = [
  {
    path: '',
    component: BlogComponent
  },
  {
    path: 'add',
    component: AddComponent
  },
  {
    path: 'edit/:id',
    component: EditComponent,
    data: {
      type: 'edit'
    }
  }

];
@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes),
    MaterialModule.forRoot(),
    FormsModule
  ],
  declarations: [BlogComponent, EditComponent, AddComponent]
})
export class BlogModule { }

To get the data or params in edit component

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params, Data } from '@angular/router';
@Component({
  selector: 'app-edit',
  templateUrl: './edit.component.html',
  styleUrls: ['./edit.component.css']
})
export class EditComponent implements OnInit {
  constructor(
    private route: ActivatedRoute,
    private router: Router

  ) { }
  ngOnInit() {

    this.route.snapshot.params['id'];
    this.route.snapshot.data['type'];

  }
}
Veerendra Borra
  • 1,286
  • 14
  • 24
  • 10
    Can you pass that data into the route at the navigation point instead of the routing configuration? For example, in a master-detail situation where the detail component replaces (so is not a child of) the master component, can you pass the master data object to the detail component while navigating to it so that the detail component can display some of its data while it's loading the detail data? – Sebastien Dec 29 '16 at 10:21
  • 3
    @Sebastien did you get your answer ...plzz tell how you did it – kumar kundan Apr 28 '17 at 09:54
  • @Veerendra Borra — I set up the router config with `data` object but in my component data still shows as empty object... any ideas? – Omar Mar 26 '18 at 22:06
2

You can do this:

app-routing-modules.ts:

import { NgModule                  }    from '@angular/core';
import { RouterModule, Routes      }    from '@angular/router';
import { PowerBoosterComponent     }    from './component/power-booster.component';


export const routes: Routes = [
  { path:  'pipeexamples',component: PowerBoosterComponent, 
data:{  name:'shubham' } },
    ];
    @NgModule({
      imports: [ RouterModule.forRoot(routes) ],
      exports: [ RouterModule ]
    })
    export class AppRoutingModule {}

In this above route, I want to send data via a pipeexamples path to PowerBoosterComponent.So now I can receive this data in PowerBoosterComponent like this:

power-booster-component.ts

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params, Data } from '@angular/router';

@Component({
  selector: 'power-booster',
  template: `
    <h2>Power Booster</h2>`
})

export class PowerBoosterComponent implements OnInit {
  constructor(
    private route: ActivatedRoute,
    private router: Router

  ) { }
  ngOnInit() {
    //this.route.snapshot.data['name']
    console.log("Data via params: ",this.route.snapshot.data['name']);
  }
}

So you can get the data by this.route.snapshot.data['name'].

Shubham Verma
  • 8,783
  • 6
  • 58
  • 79
  • 11
    What if I want to set the data dynamically? For instance, when using router.navigate()? – FelipeDrumond Feb 02 '17 at 11:42
  • 2
    Don't ask new questions via comments. Search first, then post a new question if you must. you can set the data dynamically like this:- this.router.navigate(['/detail', this.object.id]); – Shubham Verma Feb 02 '17 at 12:44
  • I notice that you can only get the `ActivatedRoute` when passing it in via DI. Why can't you obtain it from the `Router`? – The Muffin Man Feb 16 '17 at 19:27
  • 4
    @ShubhamVerma: can you please remove your comment cause it's not answering the question which is rather confusing. Your example passes data dynamically into the URL. The question is to pass data dynamically without it being reflected in the URL. – S. Robijns Jul 04 '17 at 07:42
  • @ S. Robijns: I think in my comment, i am answering how to pass data in router.navigate() And it is not confusing. Please make me sure if it is confusing . – Shubham Verma Jul 04 '17 at 10:26
1

1. Set up your routes to accept data

{
    path: 'some-route',
    loadChildren: 
      () => import(
        './some-component/some-component.module'
      ).then(
        m => m.SomeComponentModule
      ),
    data: {
      key: 'value',
      ...
    },
}

2. Navigate to route:

From HTML:

<a [routerLink]=['/some-component', { key: 'value', ... }> ... </a>

Or from Typescript:

import {Router} from '@angular/router';

...

 this.router.navigate(
    [
       '/some-component',
       {
          key: 'value',
          ...
       }
    ]
 );

3. Get data from route

import {ActivatedRoute} from '@angular/router';

...

this.value = this.route.snapshot.params['key'];
Jeremy
  • 3,620
  • 9
  • 43
  • 75