Friday, 15 December 2017

3 simple ways to share data through angular route.

Angular 2+Angular 4/5RoutingShare data

In this article I will be discussing about sharing data through routes in 3 simple ways. Compared to Angular js 1 it is so simple and there are many ways to achieve this. Let us check those one by one.

  1. Pass data using route
  2. Pass data using Query Parameters
  3. Pass data using Application Providers

1. Pass data using route


Here we are passing data directly through routes. Check below router code.

Router

Here we are passing data :{data :'Test Data'} to other component. Check below code for receiving the data.


import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { FormComponent } from './form/form.component';

export const appRoutes: Routes = [
    { path: 'home', component: HomeComponent },
    { path: 'form', component: FormComponent ,data :{data :'Test Data'} },
]

Here I am passing the data through routes. For understanding routing more check this link: - Angular routing/nested routing with examples. We need to write some code to receive this data in other component. Check below code for that.


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

@Component({
    selector: 'form',
    template: '<div>Form</div>'
})

export class FormComponent {
    sub: any;
    constructor(private route: ActivatedRoute) { }
    ngOnInit() {
        this.sub = this.route
            .data
            .subscribe(value => console.log(value));
    }
}

Similarly you can handle this logic inside your component as well. Instead of hardcoding the values in the routes, we can pass them in the component code as well. Create a clickable button in HomeComponent, on click of this button we will pass an id to FormComponent. Check below HomeComponent code.

HomeComponent


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

@Component({
  selector: 'home',
  template: '<div>Home : <button (click)="navigate();">Navigate to Form</button>'
    + '</div>'
})

export class HomeComponent {

  constructor(private router: Router) { }

  navigate() {
    this.router.navigate(['form', '0001']);
  }
}

On click of the method navigate, it will redirect to FormComponent. Inside the FormComponent we need to get the Id. Check below code for that.

FormComponent


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

@Component({
  selector: 'form',
  template: '<div>'
    + '<h4>Form</h4>'
    + '</div>'
})

export class FormComponent {
  sub: any;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
      console.log(params);
    });
  }
}

Check the console you can see the id which we passed from HomeComponent. We need to make one more changes to make it work completely. Update router code like below.


{ path: 'form/:id', component: FormComponent }

Here you can notice that I have added id along with the path form/:id. There are some scenarios you might need to read values from query parameter. This url might be redirected from somewhere. Check this article for more info: - Get Url parameter using Angular.

2. Pass data using Query Parameters


This is the one of the way we used to pass data in angular js 1 and also for other routing method as well. Advantage of using angular 2/4 is the that it wont show any thing in your url but the same time you can pass data to other component. Another advantage is that you can pass complex data using this option. Let us check with one example.

Router


import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { FormComponent } from './form/form.component';

export const appRoutes: Routes = [
    { path: 'home', component: HomeComponent },
    { path: 'form', component: FormComponent}
]

There is no additional thing here instead just routing code. Now check the component code there we will be adding a code for navigating to other page and also for sharing data.

Sharing Component


import { Component } from '@angular/core';
import { Router, NavigationExtras } from '@angular/router';

@Component({
    selector: 'home',
    template: '<div>Home : <br><button (click)="navigate();">Navigate to Form</button>'
        + '</div>'
})

export class HomeComponent {
    constructor(private router: Router) { }

    navigate() {
        let navigationExtras: NavigationExtras = {
            queryParams: {
                name: 'Prashobh',
                role: 'Angular developer'
            }
        }
        this.router.navigate(['form'], navigationExtras);
    }
}

Make sure you have imported NavigationExtras. We are passing these info to form page. Let us check FormComponent code.

Receiving component


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

@Component({
    selector: 'form',
    template: '<div>'
        + '<h4>Form</h4>'
        + '</div>'
})

export class FormComponent {
    constructor(private route: ActivatedRoute) {
        this.route.queryParams.subscribe(params => {
            console.log(params);
        });
    }
}

Here we have imported ActivatedRoute. Console the value and you can see the shared object.

3. Pass data using application providers


This is another method but it is not actually related to routes. You can use this approach to share your data across your application. We need to create a provider file first.

Provider


import { Injectable } from '@angular/core';

@Injectable()
export class DataStorage {
    public data: any;
    public constructor() { }
}

Don't forget to import your newly created provider in module. Now check our components.

Sharing component


import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { DataStorage } from "../dataProvider";


@Component({
    selector: 'home',
    template: '<div>Home'
        + '<br><button (click)="navigateToForm();">Navigate to Form</button>'
        + '</div>'
})

export class HomeComponent {

    constructor(private router: Router, private _data: DataStorage) { }

    navigateToForm() {
        this._data.data = {
            name: 'Prashobh',
            role: 'Angular developer'
        }
        this.router.navigate(['form']);
    }
}

Here we have imported our DataStorage provider and setting data to it before navigating. Now check our receiver part.

Receiving component


import { Component } from '@angular/core';
import { DataStorage } from "../dataProvider";

@Component({
    selector: 'form',
    template: '<div>'
        + '<h4>Form</h4>'
        + '</div>'
})

export class FormComponent {
    public constructor(private _data: DataStorage) {
        console.log(JSON.stringify(this._data.data));
    }
}

Import DataStorage provider here as well and just console the value.

We are done. Apart from this we can communicate with components using parent child communication logic or by making a service file common to both of the component.

In this article we have discussed about sharing data through routes with different examples.

Angular 2+Angular 4/5RoutingShare data

Related Info

1. 3 simple ways to share data through angular route.

2. Get Url parameter using Angular.

3. Share data between Angular components - 7 methods.

4. Conditionally add class using Angular - 5 methods

11 comments :

  1. Thank you so very much, worked 1st time. I really like this site it never fails me.

    ReplyDelete
    Replies
    1. Unless when it does, which may not have happened yet but still. :P

      Delete
  2. Thanks too! This is what I was looking for!

    ReplyDelete
  3. Thanks alot, I have an issue with the third method, when i refresh the page i loose all the data retrieved via the provider. What i'm i doing wrong.

    ReplyDelete
  4. I have tried the steps above and in the Receiving Component my console.log(JSON.stringify(this._data.data)); is undefined any ideas why?

    ReplyDelete
  5. Hi,
    I have checked Pass data using Query Parameters, but it showing my object data in url. Is this possible to hide the data showing in url.

    ReplyDelete
  6. In method1 instead of router function, you can also send dynamic data using routerLink="/link/{{variable}}

    and receive the data using query params as shown in the article
    ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
    console.log(params);
    });
    }

    ReplyDelete
    Replies
    1. Thanks for your comment.
      I have written one more post on the same.
      https://www.angulartutorial.net/2020/03/how-to-get-parameter-on-angular-route.html

      Delete
  7. How can I pass my id from main.ts to app.routing through url ??

    ReplyDelete