Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: sharing data across different routes

I have searched for similar questions in SO and I have not found any that addresses my specific case. There are many techniques to share data between angular components, and I have read this article about component communication: https://angular.io/docs/ts/latest/cookbook/component-communication.html

However none of the techniques described there work for me, because my components are on different routes. The article describes mostly parent-child component communication, and some cases may work for sibling components as long as they are both loaded at the same time.

My case is very similar to the Angular 2 Heroes tutorial: I have a route that displays a table with a list of customers (instead of heroes). When the user clicks on a specific customer, I trigger a route change to display a form with the data for the selected customer (instead of hero).

The heroes tutorial performs a service invocation to retrieve the selected hero data, but I want to avoid a useless additional AJAX call, given that those data are already in memory. I just want to pass the selected customer data to the customer form component so it is immediately displayed.

I am thinking of a "global session" service where I could store and retrieve any object I want, but I am not sure this is a good idea. Are there other more adequate approaches?

like image 252
Luis Crespo Avatar asked Aug 11 '16 09:08

Luis Crespo


3 Answers

use service that is provided by main application file and then inject it whenever you want to get/set data that will be available in whole app

main.app.ts

@Component({
...
  providers:[yourDataService]
...
})

other components

import {yourDataService} from '...';

@Component({
...
providers:[]// we must use provider from main file
...
})
export class someComponent{

  contructor(private myData:yourDataService){}

}

it is important to use provider from main app file because if you provide service in each component you will have another instances of your service and of course different data in each service

you can also use observables to be notified when some data has changed

for more info look at hierarchical injections or tree injector

like image 50
neuronet Avatar answered Oct 21 '22 21:10

neuronet


I'm not sure if the is is what you're after but if you need to share data across sibling routes you could try this.

Create a module Import and Declare the service in the module

import { MyService } from './my.service’;

@NgModule({
  ...
  providers: [
    MyService
  ]
  …
})

Declaring the the service in the module route means we can then pass the service by reference to the child routes. Do not use the service in the parent component

In the child route components, import the service

import { MyService } from '../my.service’;

In each component where the service should be used, do not add the service to the components metadata because we’ve already added it to the module definition. Add the service to the component constructor

export class MyChildRouteComponent implements OnInit {  
...
 constructor(
    private _myService: MyService,
    private _router: Router
  ) { }
 ...
}

If you then set a service property in one child route component, you will then be able to get it from a sibling child component.

like image 26
AJ72 Avatar answered Oct 21 '22 21:10

AJ72


What do you think about NgRx solution inspired by Redux? You can read more there - https://github.com/ngrx/store

You will have a single application store, which can be subscribed in the proper components. So - you could just dispatch an event before route changed. This soulution use only reducers, so in different ways than using store, your data would be immutable - this is the next advantage.

like image 26
Kamil Myśliwiec Avatar answered Oct 21 '22 20:10

Kamil Myśliwiec