Home > Software design >  passing object from one component to another using service file in angular
passing object from one component to another using service file in angular

Time:02-18

I am trying to draw a stacked bar chart using Kendo UI and angular. I want to pass data from home component to stacked bar chart component using service file. Home component console shows the dataset correctly but stacked bar chart component does not get the data as input.

Home component.ts

import { Component } from '@angular/core';
import { HomeService } from './home.service';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent {
  homeData: any = [];
  stackedbarchartdata: any = [];
  constructor(private Data: HomeService) {
    this.Data.getMethod().subscribe((res: any) => {
      this.homeData = res;
      this.stackedbarchartdata = this.homeData.stackedbarchartdata;
      console.log(this.stackedbarchartdata);
    })
  }
  ngOnInit() {}
}

home component.html

<kendo-tilelayout-item [col]="3" [colSpan]="2">
  <kendo-tilelayout-item-body>
    <app-stacked-bar-chart [stackedbarchartdata]="stackedbarchartdata"></app-stacked-bar-chart>
  </kendo-tilelayout-item-body>
</kendo-tilelayout-item>

stacked-bar-chart.component.ts

import { Input } from '@angular/core';
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-stacked-bar-chart',
  templateUrl: './stacked-bar-chart.component.html',
  styleUrls: ['./stacked-bar-chart.component.css']
})
export class StackedBarChartComponent implements OnInit {
  @Input() stackedbarchartdata: any;
  ngOnInit() {
    console.log(this.stackedbarchartdata);
    }
}

Json Data

"singleBaChartData": {
    "name": "singleBaChartData-TOTAL REVENUE",
    "Title": "TOTAL REVENUE",
    "singleBaChartData": [{ "id": 1,"category": "product1","value": 5},
      { "id": 2,"category": "product2","value": 4}]}

CodePudding user response:

I am not familiar with Kendo TileLayout and based on your comment, I can only assume the change detection of kendo-tilelayout-item isn't picking up the changes to stackedbarchartdata property. There are multiple options to try

1. Use async pipe

You could remove the subscription in the component controller and use async pipe in the template instead. This should trigger the subscription right from the template the provide the data to the @Input() variable.

import { Component } from '@angular/core';
import { HomeService } from './home.service';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent {
  homeData: any = [];
  stackedbarchartdata$: Observable<any>;

  constructor(private Data: HomeService) {
  }

  ngOnInit() {
    this.stackedbarchartdata$ = this.Data.getMethod().pipe(
      tap((res: any) => this.homeData = res),       // <-- is this needed anymore?
      map((res: any) => res.stackedbarchartdata)
    );
  }
}
<kendo-tilelayout-item [col]="3" [colSpan]="2">
  <kendo-tilelayout-item-body>
    <app-stacked-bar-chart [stackedbarchartdata]="stackedbarchartdata$ | async"></app-stacked-bar-chart>
  </kendo-tilelayout-item-body>
</kendo-tilelayout-item>

2. Manually trigger change detection

There are multiple ways to trigger the change detection manually inside the subscription callback after the property stackedbarchartdata is assigned the value. Although I find this a little inelegant.

  • Related