Search code examples
angularangular2-routingangular2-components

Angular2 pass data to route from component


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?


Solution

  • 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;
        }
    }