Home > Blockchain >  Save the data get using service file angular
Save the data get using service file angular

Time:03-03

I am trying to create a chart in angular and I get data using a service. I want to use the array data get from here. pieData: any = []; The console inside the constructor show the data correctly. but the console inside the ngOnInit shows empty array.

import { Component, OnInit } from '@angular/core';
import { PieChartService } from './pie-chart.service';
@Component({
  selector: 'app-pie-chart',
  templateUrl: './pie-chart.component.html',
  styleUrls: ['./pie-chart.component.css']
})
export class PieChartComponent implements OnInit {
  pieData: any = []; 

  constructor(private PieChart: PieChartService) {
    this.PieChart.getMethod().subscribe((res: any) => {
      this.pieData = res.pieData;
      console.log(this.pieData);
    })
  }
  ngOnInit() { }
 //code for create a graph here
}

CodePudding user response:

What you can try is to move the subscription inside the ngOnInit hook, so that you can write your code or call the function for creating the chart from inside the subscription. Though I am not sure why would you need the subscription inside the constructor but I would say that it is not a best practice to do work inside the constructor as it is mostly used for initalizing class members. Whereas ngOnInit is called after all data bound properties of your component has been intialized.

Also quoting Difference between ngOnInit and constructor

Mostly we use ngOnInit for all the initialization/declaration and avoid stuff to work in the constructor. The constructor should only be used to initialize class members but shouldn't do actual "work".

So you should use constructor() to setup Dependency Injection and not much else. ngOnInit() is better place to "start" - it's where/when components' bindings are resolved.

The solution to your problem would be:

pieData$: Subscription; // subscription for data
ngOnInit() { 
  this.pieData$ = this.PieChart.getMethod().subscribe((res: any) => {
    this.pieData = res.pieData;
    console.log(this.pieData);
    //code for create a graph here
  })
}

Also don't forget to unsubscribe to the subscription on Destroy

ngOnDestroy() {
  this.pieData$.unsubscribe();
}

CodePudding user response:


Alternative: Using a Promise

pie-component.ts

import { Component, OnInit } from '@angular/core';
import { PieChartService } from './pie-chart.service';

@Component({
    selector: 'app-pie-chart',
    templateUrl: './pie-chart.component.html',
    styleUrls: ['./pie-chart.component.css'],
})
export class PieChartComponent implements OnInit {
    pieData: any = [];

    constructor(private PieChart: PieChartService) {
        console.log('[PieChartComponent]', '[constructor]');
    }

    async ngOnInit() {
        console.log('[PieChartComponent]', '[OnInit]');
        // Follwoing promise is `await`-ed, so execution proceeds once that finishes,
        // and after which this.pieData will be set and can be accessed for values 
        // from anywhere else in the component's lifecycle hooks or any other operations 
        // that it supports. Enclose within a try-catch for error handling
        const pieDataResponse = await this.PieChart.getMethod().toPromise();
        this.pieData = pieDataResponse?.pieData || [];
        console.log('[PieChartComponent]', '[pieData]', '[Received]', this.pieData);
        //code for create a graph here
    }
}

WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET

  • Related