Search code examples
angulartypescriptangular2-routingangular2-components

How to pass variable from one component to another component and print that variable in 2nd Component template html file?


I am having a dashboard which has list of groups the logged in user is. Now as user clicks on any of the group, basic information of the group like name, description etc are printed on the right side of the page.It is something like this.enter image description here

HomeComponent has child component called GroupComponent. I am trying to pass the group object from HomeComponent to GroupComponent which will print the name of it. Below is the code which I have tried:

routes.ts

export const routes: Routes = [
  {path: '', redirectTo: 'home', pathMatch: 'full'},
  {path: 'login', component: LoginComponent},
  {
    path: 'home', component: HomeComponent, canActivate: [AuthGuard],
    children: [
      {path: '', redirectTo: 'dashboard', pathMatch: 'full'},
      {path: 'group', component: GroupComponent},
      {path: 'dashboard', component: DashboardComponent}
    ]
  }
];

home.component.ts

export class HomeComponent implements OnInit {
  user: string;
  user_id: number;
  group_list: string[];

  constructor(public router: Router, private _groupService: GroupService) {
    // xyz code
  }

  ngOnInit() {
  }

  getUserGroups() {
    let body: string = '{}';
    this._groupService.getAllUserGroups(body).subscribe(
      auth => {
        let payload = auth.json();
        this.group_list = payload.list;
      },
      error => {
        console.log(error);
      }
    );
  }

  goToGroupDetail(group) {
    console.log(group.id);
    let groupObj = new GroupComponent(group.name);
    this.router.navigate(['/home/group']);
  }

}

home.component.html

<ul class="nav navbar-nav navbar-right">
            <li *ngFor="let group of group_list"><a  (click)="goToGroupDetail(group);">{{group.name}}</a></li>
          </ul>

group.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-group',
  templateUrl: './group.component.html',
  styleUrls: ['./group.component.css']
})
export class GroupComponent implements OnInit {
  group_name:string;

  getGroupName(): string {
    return this.group_name;
  }

  setGroupName(value){
    this.group_name = value;
  }

  constructor(name:string) {
    this.setGroupName(name);
  }
  ngOnInit() {
  }

}

group.component.html

<p>
  group works!
</p>
<div class="col-md-6">
  <h2>Name of the Group : {{group_name}}</h2>
</div>

I am getting this kind of error : enter image description here


Solution

  • You are trying to something that cannot be done... meaning the following line: let groupObj = new GroupComponent(group.name); and then expect to be able to get the value injected in constructor.

    The most common scenario here to share data between components is to use a shared service.

    Sp use a shared service with BehaviorSubject Before routing, set the group, and then in your GroupComponent subscribe to the subject.

    In your GroupService, import BehaviorSubject and declare the following:

    import {BehaviorSubject} from 'rxjs/BehaviorSubject';
    
    private group = new BehaviorSubject<string>(null);
    
    group$ = this.group.asObservable();
    
    emitGroup(group: string) {
      this.group.next(group);
    }
    

    And in your HomeComponent pass the group to Service:

    goToGroupDetail(group) {
      console.log(group.id);
      this._groupService.emitGroup(group); // here
      this.router.navigate(['/home/group']);
    }
    

    And then in your GroupComponent you can subscribe to this in the constructor:

    constructor(private _groupService: GroupService) {
      _groupService.group$.subscribe(group => {
         this.group_name = group; // assign value here
      });
    }
    

    More about shared service from the official docs.