Angular2 pass data to route from component

kemsbe picture kemsbe · Dec 21, 2016 · Viewed 8.1k times · Source

I need to pass data from one component to another, I found only the way to do it with route parameters in url:

So I have such configuration for target component in router:

{
    path: 'edit-tags/:type/:name/:id',
    component: EditTagsComponent,
},

And I use it like that from another component:

this.router.navigate([`../edit-tags/${product.type}/${product.name}/${product.id}`], { relativeTo: this.route });

It works ok, but I don't want to show id in url and also need to pass some more data to the component.

Also I've seen using configurations like that in router:

{ path: 'test-product', component: ProductsContentComponent, data: { role: 'admin', type: 'test-product' } }

But I haven't found an example of using the same approach inside another component.

So, is there a way to pass some data from component to component on routing without reflecting it in url?

Answer

aholtry picture aholtry · Dec 21, 2016

We needed the same solution for our web app and we took the approach of passing data from one component to another through a service. This way, sensitive data is not expressed in the URL. Here is our first component that shows a list of data. The main method we are focusing on is the changeRoute method. Prior to route change, we save the currently selected data to the dataService and then perform a route change.

import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";

import { DataService } from "./data.service";
import { Data } from "../../models/data.model";

@Component({
selector: "ei-data-list",
template: require("./data-list.component.html")
})
export class DataListComponent implements OnInit {
    constructor(private dataService: DataService, private router: Router) {}

    // .... code for properties and getting data here

    changeRoute(data: Data) {
        this.dataService.data = data;
        this.router.navigate(["/data-list/data-item"]);
    }
}

Here is the data service that we built. For this example we trimmed it down a bit.

import { Injectable } from "@angular/core";
import { Data } from "../../models/data.model";

@Injectable()
export class DataService {
    constructor() { }

    public data: Data;
}

Finally we have our second component which we are passing the data. Inside the ngOnInit, we are gathering the data so it is ready when the page loads. I hope this helps.

import { Component } from "@angular/core";
import { DataService } from "./data.service";

@Component({
    selector: "ei-data-item",
    template: require("./data.component.html")
})
export class DataComponent {
    constructor(private dataService: DataService) {}
    data: Data;

    ngOnInit() {
        this.data = this.dataService.data;
    }
}