Let me explain first what the working part is in my project:
dataframe.component
: A button is emitting an event which calls a function Initdf()
which initiates a service which retrieves JSON data from my backend API. I map two values from this data and assign them to arrays. dfClose
and dfDateTime
.
With these two arrays I want to feed a plotly.js
chart in plotly1.component
I'm trying to achieve the data sharing between the components with @Input()
and @Output()
properties.
What is not working:
In my plotly1.component, I imported the onChanges method to listen to updates on the data (when button is clicked), but I get tons of repeated error messages:
core.mjs:6485 ERROR TypeError: Cannot read properties of undefined (reading 'data')
I cannot complete the onChanges method because the angular doc is not detailed enough for me. I can't help myself with it alone.
dataframe.component.ts:
import { Component, OnInit, Output } from '@angular/core';
import { RestServiceDfinit } from '../../services/rest-df-init.service';
import { DfIndicatorService } from '../../services/rest-df-indicator.service';
import {Plotly1Component} from '../plotly1/plotly1.component';
@Component({
selector: 'app-dataframe',
templateUrl: './dataframe.component.html',
styleUrls: ['./dataframe.component.scss']
})
export class DataframeComponent implements OnInit {
df_array: any = [];
tabVal:any = [];
tabKey:any = [];
df_standard_tab_order: any;
toggleAdd: boolean = true;
toggleDelete: boolean = true;
@Output() dfClose:any;
@Output() dfDateTime:any;
constructor(private restService: RestServiceDfinit, private indicatorService: DfIndicatorService) {}//, private plotly: Plotly1Component) {}
ngOnInit(): void { }
Initdf() {
this.restService.postTickerGetDf().subscribe((response) => {
this.df_array = response;
this.dfClose = this.df_array.map((x: any) => x.Close);
this.dfDateTime = this.df_array.map((x: any) => x.DateTime);
.....
plotly1.component.ts:
import { Component, OnInit, Input, OnChanges } from '@angular/core';
import {Plotly1Service} from '../../services/plotly1.service'
import {Observable} from 'rxjs'
@Component({
selector: 'app-plotly1',
template: '<plotly-plot [data]="graph.data" [layout]="graph.layout"></plotly-plot>'
})
export class Plotly1Component implements OnChanges {
public graph:any;
@Input() dfClose:any;
@Input() dfDateTime:any;
constructor(private plotlyService: Plotly1Service) { }
ngOnChanges(changes: SimpleChanges): void {
this.fill_data();
}
fill_data() {
this.graph = {
data: [
{ x: this.dfDateTime, y: this.dfClose, type: 'scatter', mode: 'lines', marker: {color: 'blue'} },
],
layout: {width: 1320, height: 600, title: 'test Plot'}}}}
Is it the right path to go with onChanges? How to I complete it?
Update: I skipped the plotly.component for testing and tried to get the data from setData
in dataframe.component.ts in a div
:
Initdf() {
this.restService.postTickerGetDf().subscribe((response) => {
this.df_array = response;
const close = response.map(x => x.Close);
const dateTime = response.map(x => x.DateTime);
this.mappedData.emit({
dfClose: close,
dfDateTime: dateTime
});
this.setData(this.mappedData);
setData(mappedData:any) {
this.dfClose = mappedData.dfClose;
this.dfDateTime = mappedData.dfDateTime;
this.graph = {
data: [
{ x: this.dfDateTime, y: this.dfClose, type: 'scatter', mode: 'lines', marker: {color: 'blue'} },
],
layout: {width: 1320, height: 600, title: 'test Plot'}}
in dataframe.component.html I tried these variations:
<div (mappedData)="setData($event)">{{graph}}</div>
<div (mappedData)="setData($event)">{{mappedData}}</div>
<div >{{graph}}</div>
<div >{{mappedData}}</div>
It also doesn't work. In the best case I see [object Object]
I found the solution by myself. It works well with my initial idea to use the OnChanges
lifecycle hook.
dataframe component ts:
Initdf() {
this.restService.postTickerGetDf().subscribe((response) => {
this.df_array = response;
dataframe html:
<app-plotly1 [df_array]="df_array"></app-plotly1>
plotly1 component ts:
@Input() df_array:any;
ngOnChanges(changes: SimpleChanges): void {
this.dfClose = this.df_array.map((x: any) => x.Close);
this.dfDateTime = this.df_array.map((x: any) => x.DateTime);