There was a recent question over on Stack Overflow about sharing data between two components on different routes. My short answer was to use a Service. But, the OP said in a thread:

I have now realised that passing data through components when they are on separate routes requires a different solution

That just didn't seem right to me, so I threw together this experiment on how to user Services to share data when they are on two different routes.

The Setup

First, let's do some setup. Create an Angular application. Run this at your command prompt:

view plain print about
1ng new

You'll see this:

I set up Angular routing and used regular CSS.

Then generate two new components, and a service:

view plain print about
1ng generate component comp1
2ng generate component comp2
3ng generate service shareddata

Your directory structure should look something like this:

You see your two components, and the service all created in the app.

I want to load one Angular module into our app: the Angular FormsModule. Load up the app.module.ts, and import the lib:

view plain print about
1import {FormsModule} from '@angular/forms';

And the put it in the import of the NgModule declaration:

view plain print about
1imports: [
2 BrowserModule,
3 AppRoutingModule,
4 FormsModule
5 ],

We'll use the ngModel directive to change data in a service.

Set up Routing

Open up the app-routing.module.ts file and set up a few routes:

view plain print about
1const routes: Routes = [
2 { path: 'view1', component: Comp1Component },
3 { path: 'view2', component: Comp2Component },
4 { path: '**', redirectTo: 'view1' },
5];

The default route redirects to view1, which uses Comp1Component. The view2 route uses Comp2Component.

Open up app.component.html. Delete all the contents and replace it with the router outlet:

The router outlet is a special Angular tag which says "output the elements from the router here.

Let's add some navigation between these routes. Open up comp1.component.html:

view plain print about
1<a routerLink="/view2">To Route 2</a><br/><br/>

And open up comp2.component.html:

view plain print about
1<a routerLink="/view1">To Route 1</a><br/><br/>

The routerLink is use to navigate between the two routes.

Let's give it a shot. Run the app:

view plain print about
1ng serve

And then point your browser to localhost:4200. It should start at route2. You can see it in the URL and that the link sends you to route 2:

Click the link:

You should see the route change in the browser URL and the link to send you back to route 1. We got this working.

Set up the Service

Let's set up two values in the service. Open up shareddata.service.ts in the src directory of the app:

view plain print about
1valueOnRoute1 = 'default value on route 1';
2 valueOnRoute2 = 'default value on route 2';

I added one value that can be viewed on route 1, but changed on route 2. And one value to viewed set on Route 2, but can be changed on route 1. This will show how the two views can share data using a service.

Let's be sure to inject the service into each of our components. Open up comp1.component.ts and inject the ShareddataService:

view plain print about
1constructor(public sharedDataService: ShareddataService) { }

And do the same for comp2.component.ts:

view plain print about
1constructor(public sharedDataService: ShareddataService) { }

Both class files will need the same import:

view plain print about
1import {ShareddataService} from '../shareddata.service';

Note: I hate that I messed up the camel case on this file, but didn't want to change the screenshots.

Setup the Input and Display

We have one value, valueOnRoute1 that we want to edit in Route 1. And one value, valueOnRoute2, that we want to edit on Route 2.

Open up comp1.component.html:

view plain print about
1Value Edited on Route 1: <input [(ngModel)]="sharedDataService.valueOnRoute1" /><br/><br/>
2Value Edited on Route 2: {{sharedDataService.valueOnRoute2}}

We use a standard HTML input along with ngModel to allow for editing and displaying valueOnRoute1 value. For the valueOnRoute2 we just use curly brackets to display the value.

In comp2.component.html we do the exact opposite:

view plain print about
1Value Edited on Route 1: {{sharedDataService.valueOnRoute1}}<br/><br/>
2Value Edited on Route 2: <input [(ngModel)]="sharedDataService.valueOnRoute2" />

The valueOnRoute1 is displayed with curly brackets. The valueOnRoute2 is editable with an input and the ngModel.

See this Working

Once again point your browser to localhost:4200. You'll start at route 1:

You can see that both the input and display show the values we set as defaults inside the service. The first value can be edited, while the second is just a display. Switch over to route 2:

You'll see the first value is uneditable, but still displaying the service value. The second value is editable, also displaying the default service value. Let's go back to route 1 and edit:

I changed the value from "Default Value on Route 1" to "Edited Route 1". Click over to Route 2:

You see that the valueOnRoute1 retains the value we changed it to on view 1. The valueOnRoute2 is unchanged so far, but let's change it:

Now, switch back to Route 1:

You see that the valueOnRoute1 remains unchanged after our first edit. The valueOnRoute2 also displays its edited value.

Final Thoughts

This demo shows how you can use a service to share data between two different components on two different routes.

Play with the code over here, and thanks for reading.