angular2 - Pass value from parent route to child route
Asked Answered
M

2

7

I have a route called home and it has three child routes, documents, mail and trash. In the home route component it has a variable called 'user'. I know there are a few ways of passing info between parent and child components highlighted here, but how am I suppose to pass info between parent/child routes.

{ path: 'home',  component: HomeComponent, children: [
        { path: 'documents',  component: DocumentsComponent },
        { path: 'mail',  component: MailComponent },
        { path: 'trash',  component: TrashComponent },
    ]
},

Service

import { Injectable } from '@angular/core';
@Injectable()
export class HomeService {
  // Mock user, for testing  
  myUser = {name:"John", loggedIn:true};
  // Is Super Admin
  isLogged():boolean {
    if(this.myUser.role == true){
      return true ; 
    }
    return false ; 
  }
}

Component

  constructor(public router: Router, public http: Http, private homeService: HomeService) {

  }

  isLogged(){
    return this.homeService.isLogged(); 
  }

Template

<div class="side-nav fixed" >
    <li style="list-style: none">
        <img alt="avatar" class="circle valign profile-image" height="64" src=
        "../images/avatar.jpg" width="64">
        <div class="right profile-name">
            <!-- Value not changing even with service --> 
            {{myUser.role}} 
        </div>
    </li>

Mouth answered 3/8, 2016 at 2:43 Comment(0)
C
7

You may use a common service to pass data like explained in the Angular Documentation

Basically you may create a Service which will have a user object, which can be updated once your parent route gets loaded or with some action on parent component.

UserService

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

   @Injectable()
   export class UserService {
     // Observable user 
     user = new Subject<string>();
   }

And then when the child route component gets loaded you may retrieve the value from the Service.

HomeComponent

 @Component({
   ... 
 })
 export class HomeComponent{
   ... 
   constructor(private userService:UserService ){}
   someMethod = () =>{
      this.userService.user.next(<pass user object>);
   }
 }

MailComponent

 @Component({
   ... 
 })
 export class HomeComponent{
   ... 
   constructor(private userService:UserService ){
     this.userService.user.subscribe(userChanged);  
   }

   userChanged = (user) => {
     // Do stuff with user
   }
 }

Service object will be same instance in child if you add the provider in the parent.

Cod answered 3/8, 2016 at 2:59 Comment(12)
Doesn't work for you as in, you are not able to implement this or you have some different scenario? If different scenario please add more details.Cod
In my html template i have an ngIf to check if the user is logged in. However, its not reading the service method that checks.Mouth
you may add a variable which can be updated based upon the subscription, and use it in the ngIf in child component.Cod
Yeah that could work. So im giong to have to import this service for every component i have ? Is there another way?Mouth
Okay, so i tried the variable thing you suggested and that works, but when i try change the user info, the parent and child are not talking. One will have the user logged in and the other will have the user logged out.Mouth
are you calling this.userService.user.next(new user info object) again when you change user info in parent?Cod
Im not using the methods you pulled off the website, im using my own.Mouth
I guess ill just have to make a new question to figure out why the service info doesn’t change. Thanks anywayMouth
user: Subject<string> = new ReplaySubject(1) works for meOphthalmitis
I understand the simple case here, where the service is used essentially like a simple shared global object - but how does this work if I have multiple instances of main component - in tabs or in a list. Does the DI container automatically give the same instance to the child or do I have to manage some kind of additional 'key' if I'm sharing this service?Tailgate
To followup, the section "Parent and children communicate via a service" from angular.io/guide/component-interaction#!#bidirectional-service explains that The scope of the service instance is the parent component and its children. Components outside this component subtree have no access to the service or their communications.Tailgate
@MadhuRanjan "Service object will be same instance in child if you add the provider in the parent." This sentence saved my life. :)Serdab
C
2

Check out :- https://angular.io/docs/ts/latest/guide/router.html#!#link-parameters-array

You can pass data while changing routes on click as :-

<a [routerLink]="['/crisis-center', { foo: myVar }]">Crisis Center</a>
Capsulize answered 3/8, 2016 at 5:35 Comment(1)
How and where do you access that object passed? ActivatedRoute.data?Dubrovnik

© 2022 - 2024 — McMap. All rights reserved.