The chart.js/ng2-charts is not displaying the data given - html

I've developed a website in Angular 14 that treat about cryptocurrencies using the CoinGecko API.
I wanted to display a chart for every cryptocurrency on a specific page using chart.js and ng2-charts.
I've parsed the data sent by the API and used it in my chart but it is not showing the line chart expected.
Here is a service that is getting the data from the API and parse it:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import {map, Observable, Subscription } from 'rxjs';
#Injectable({
providedIn: 'root',
})
export class SingleCryptoGraphService {
subscription: Subscription;
doubletab: any = {
date : Array<string>(),
price: Array<number>(),
};
constructor(private httpClient: HttpClient) {
this.subscription = Subscription.EMPTY;
}
HistoricalChart(id: string, currency: string, days: number): Observable<any> {
return this.httpClient
.get<any[]>(
'https://api.coingecko.com/api/v3/coins/'+id+'/market_chart?vs_currency='+currency+'&days='+days+'&interval=daily').pipe(
map( (obj: any) => obj['prices']),
map((tab: any[]) => {
const res = [];
for (let i = 0; i < tab.length; i++) {
this.doubletab.date.push(this.getDate(tab[i][0]));
this.doubletab.price.push(this.convertToNumber(tab[i][1]));
}
console.log(this.doubletab);
return this.doubletab;
}
)
);
}
getDate = (date: number) : string => {
let d = new Date(date)
let day = d.getDate()
let month = d.getMonth() + 1
let year = d.getFullYear()
return day + "/" + month + "/" + year
}
convertToNumber = (str: string) : number => {
return Number(str)
}
}
Here is the chart component TypeScript:
import { Component, OnDestroy, OnInit, Input, ViewChild } from '#angular/core';
import { SingleCryptoGraphService } from '../single-crypto-graph.service';
import { Subscription } from 'rxjs';
import { Chart, ChartConfiguration, ChartEvent, ChartType } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts';
#Component({
selector: 'app-crypto-graph',
templateUrl: './crypto-graph.component.html',
styleUrls: ['./crypto-graph.component.css']
})
export class CryptoGraphComponent implements OnInit, OnDestroy {
subscription3: Subscription
chartInfoTabs: any = {
date: Array<string>(),
price: Array<number>(),
}
#Input() id = ''
constructor(private SingleCryptoGraphService:SingleCryptoGraphService) {
this.subscription3 = Subscription.EMPTY;
this.id = "none";
}
ngOnInit(): void {
this.subscription3.unsubscribe()
this.subscription3 = this.SingleCryptoGraphService.HistoricalChart(this.id,"eur",30).subscribe(
(data) => {
this.chartInfoTabs.date = data.date;
this.chartInfoTabs.price = data.price;
}
);
}
ngOnDestroy() {
this.subscription3.unsubscribe()
}
public lineChartData: ChartConfiguration['data'] = {
datasets: [{
data: this.chartInfoTabs.price,
label: this.id,
backgroundColor: 'rgba(148,159,177,0.2)',
borderColor: 'rgba(148,159,177,1)',
pointBackgroundColor: 'rgba(148,159,177,1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(148,159,177,0.8)',
fill: 'origin',
}],
labels: this.chartInfoTabs.date,
}
public lineChartOptions: ChartConfiguration['options'] = {
elements: {
line: {
tension: 0.5
}
},
scales: {
y:
{
position: 'left',
},
},
};
public lineChartType: ChartType = 'line';
#ViewChild(BaseChartDirective) chart?: BaseChartDirective;
}
And here is the canvas used to display the chart and the result I got:
<canvas baseChart class="chart"
[data]="lineChartData"
[options]="lineChartOptions"
[type]="lineChartType"
(chartHover)="chartHovered($event)">
</canvas>
What's actually shown by my code
I suspect my tables of data implement the wrong type but I can't figure out why because they seem to be right.
I would really appreciate help with this problem because I really don't understand why it is not working.

Related

Type 'Data' is missing the following properties from type

I'm new to Angular 8 and wondering why im getting this error, also if you see a better way to write the following code please don't hesitate to give me tips.
Type 'Data' is missing the following properties from type 'Documentary': id, > title, slug, storyline, and 13 more.
The error is here in AdminDocumentaryEditComponent
ngOnInit() {
this.route.data.subscribe(data => {
this.documentary = data; //here
console.log(this.documentary);
this.initForm();
})
}
DataService
import { HttpClient, HttpParams } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private url: string, private http: HttpClient) { }
get(slug) {
return this.http.get(this.url + '/' + slug);
}
getAll(params:HttpParams) {
return this.http.get<Object[]>(this.url,
{
params: params
});
}
create(resource) {
return this.http.post(this.url, JSON.stringify(resource));
}
update(resource) {
return this.http.put(this.url + '/' + resource.id, JSON.stringify({
}));
}
delete(id: number) {
return this.http.delete(this.url + '/' + id);
}
}
DocumentaryService
import { HttpClient } from '#angular/common/http';
import { DataService } from './data.service';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class DocumentaryService extends DataService {
constructor(http: HttpClient) {
super('http://localhost:8000/api/v1/documentary', http);
}
}
DocumentaryResolverService
import { Documentary } from './../models/documentary.model';
import { DocumentaryService } from './documentary.service';
import { Injectable } from '#angular/core';
import {
Resolve,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '#angular/router';
#Injectable({ providedIn: 'root' })
export class DocumentaryResolverService implements Resolve<Documentary> {
constructor(private documentaryService: DocumentaryService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let slug = route.params['slug'];
let documentary = this.documentaryService.get(slug)[0];
return Object.assign(new Documentary(), documentary);
}
}
AdminDocumentaryEditComponent
import { Documentary } from './../../../models/documentary.model';
import { DocumentaryService } from './../../../services/documentary.service';
import { Params, ActivatedRoute, Router } from '#angular/router';
import { Component, OnInit, ViewChild, ChangeDetectorRef } from '#angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '#angular/forms';
import { AngularEditorConfig } from '#kolkov/angular-editor';
#Component({
selector: 'app-admin-documentary-edit',
templateUrl: './admin-documentary-edit.component.html',
styleUrls: ['./admin-documentary-edit.component.css']
})
export class AdminDocumentaryEditComponent implements OnInit {
documentary: Documentary;
editDocumentaryForm: FormGroup;
constructor(
private route: ActivatedRoute,
private documentaryService: DocumentaryService,
private router: Router,
private cd: ChangeDetectorRef) {}
editorConfig: AngularEditorConfig = {
editable: true,
spellcheck: true,
height: '25rem',
minHeight: '5rem',
placeholder: 'Enter text here...',
translate: 'no',
uploadUrl: 'v1/images', // if needed
};
ngOnInit() {
this.route.data.subscribe(data => {
this.documentary = data;
console.log(this.documentary);
this.initForm();
})
}
initForm() {
let title = this.documentary.title;
let slug = this.documentary.slug;
let storyline = this.documentary.storyline;
let summary = this.documentary.summary;
let year = this.documentary.year;
let length = this.documentary.length;
let status = this.documentary.status;
let short_url = this.documentary.short_url;
let poster = this.documentary.poster;
this.editDocumentaryForm = new FormGroup({
'title': new FormControl(title, [Validators.required]),
'slug': new FormControl(slug, [Validators.required]),
'storyline': new FormControl(storyline, [Validators.required]),
'summary': new FormControl(summary, [Validators.required]),
'year': new FormControl(year, [Validators.required]),
'length': new FormControl(length, [Validators.required]),
'status': new FormControl(status, [Validators.required]),
'short_url': new FormControl(short_url, [Validators.required]),
'poster': new FormControl(poster, [Validators.required])
});
this.editDocumentaryForm.statusChanges.subscribe(
(status) => console.log(status)
);
}
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.editDocumentaryForm.patchValue({
poster: reader.result
});
// need to run CD since file load runs outside of zone
this.cd.markForCheck();
};
}
}
onSubmit() {
console.log(this.editDocumentaryForm);
}
}
In routing make sure to name resolver with the same name 'data':
{ path: 'somepath', component: AdminDocumentaryEditComponent, resolve: { data: DocumentaryResolverService} }

How to get JSON data into Dialog Component

Before this, the JSON Data appears when hovering over the info icon. Now i wish to pass the JSON Data into a dialog when click the info icon. But i dont know how.
HTML
<h2 mat-dialog-title>Info</h2>
<mat-dialog-actions>
<button mat-button (click)="matDialogRef.close()">Ok</button>
</mat-dialog-actions>
Dialog-Component.ts
import { Component, OnInit, Input, Inject, ViewEncapsulation, HostListener } from '#angular/core';
import { MAT_DIALOG_DATA, MatDialogRef} from '#angular/material';
import { FormBuilder, FormGroup, FormControl, Validators } from '#angular/forms';
import { PlannerProject } from 'app/services/planner-projects/planner-project';
#Component({
selector: 'app-my-dialog',
templateUrl: './my-dialog.component.html',
styleUrls: ['./my-dialog.component.scss']
})
export class MyDialogComponent implements OnInit {
#Input() project: PlannerProject;
projectData: string;
constructor(public matDialogRef: MatDialogRef<MyDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any) { }
ngOnInit() {
}
ngOnChanges(event): void {
if (event.project !== undefined) {
this.projectData = JSON.stringify(this.project, null, 2);
}
}
ok(): void {
this.matDialogRef.close();
}
}
Delivery-Order.Component.ts
import { DeliveryOrderEditComponent } from './../delivery-order-edit/delivery-order-edit.component';
import { SelectionModel } from '#angular/cdk/collections';
import { Component, OnInit, ViewChild, OnDestroy, ElementRef, Input, OnChanges } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { PlannerProjectsService } from 'app/services/planner-projects/planner-projects.service';
import { map, switchMap, tap, debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { DeliveryOrdersService } from '../delivery-orders.service';
import { Observable, of, Subscription, fromEvent } from 'rxjs';
import * as moment from 'moment';
import { MatPaginator, MatSort, PageEvent, MatTableDataSource, MatDialog } from '#angular/material';
import * as _ from 'lodash';
import { FuseSidebarService } from '#fuse/components/sidebar/sidebar.service';
import { DeliveryOrder } from '../delivery-order';
import { MyDialogComponent } from './../my-dialog/my-dialog.component';
import { PlannerProject } from 'app/services/planner-projects/planner-project';
import { FuseConfirmDialogComponent } from '#fuse/components/confirm-dialog/confirm-dialog.component';
import { UploadExcelService } from 'app/services/upload-excel.service';
#Component({
selector: 'app-delivery-orders',
templateUrl: './delivery-orders.component.html',
styleUrls: ['./delivery-orders.component.scss']
})
export class DeliveryOrdersComponent implements OnInit, OnDestroy, OnChanges {
#Input() project: PlannerProject;
#ViewChild(MatPaginator) paginator: MatPaginator;
#ViewChild(MatSort) sort: MatSort;
selection: SelectionModel<DeliveryOrder>;
importId: string;
dataTable;
sub: Subscription;
projectData : string;
// _filter: string;
_sortBy: string;
_sortOrder = 'asc';
_pageSize = 10;
_pageIndex = 1;
_options = {
pageSize: 100,
pageSizeOptions: [100, 150, 200, 250]
};
_displayedColumns = [
{ displayName: 'Location Name', column: 'locationName', sort: true },
{ displayName: 'Delivery Address', column: 'address', sort: false },
{ displayName: 'Is Valid', column: 'isValid', sort: false },
{ displayName: 'Import At', column: 'importedAt', sort: false },
{ displayName: 'File Name', column: 'importFileName', sort: false },
// { displayName: '', column: '' },
// { displayName: '', column: '' },
];
_displayColumns: string[] = ['selectRow', 'locationName', 'address', 'quantity', 'weight', 'volume', 'remarks', 'importedAt', 'actions'];
_actions = [
{
text: 'Edit',
action: (row) => {
console.log(`row`, row);
}
}
];
_dataSource: MatTableDataSource<DeliveryOrder>; // = new DeliveryOrdersDataSource(this.deliveryOrderService, '');
_filter: string | Observable<string>;
// #ViewChild('listHeader') listHeader: PageListTemplateComponent;
#ViewChild('search') search: ElementRef;
constructor(private route: ActivatedRoute,
private router: Router,
private projectService: PlannerProjectsService,
private deliveryOrderService: DeliveryOrdersService,
private uploadExcelService: UploadExcelService,
private _matDialog: MatDialog) { }
openDialog(): void {
const Ref = this._matDialog.open(MyDialogComponent, {
});
Ref.afterClosed().subscribe(result => {
console.log('The dialog was closed');
console.log(result);
});
}
ngOnInit(): void {
this.initDataTable();
}
ngOnDestroy(): void {
console.log(`destroy`);
if (this.sub) {
this.sub.unsubscribe();
}
}
ngOnChanges(): void {
if (this.project !== undefined) {
this.projectData = JSON.stringify(this.project, null, 2);
this.loadList(this.project.importId).toPromise().then((data) => {
console.log(`data`, data);
_.map(data, this.formatData.bind(this));
this.dataTable = data;
this._dataSource.data = this.dataTable;
this.selection = new SelectionModel<DeliveryOrder>(true, []);
});
}
So when i click the info icon, it shall display the JSON data in the dialog box. i also added the Delivery-order.component. I dont know much about JSON, so im very weak in trying to solve this problem to make the JSON values show up
When you create your dialog in delivery-component you can define input data for your dialog component, in this way:
const Ref = this._matDialog.open(MyDialogComponent, {
data: { id: 'id-value' }
});
Then you can recover your data in your dialog component:
constructor(public matDialogRef: MatDialogRef<MyDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any) {
console.log(this.data.id);
}
In this example this.data will contain the data passed from your main component to dialog, the id field is only an example, you can pass whatever you want to dialog component.
Try something like this.
First method will open dialog and will pass all the data of the project
openDialog(): void {
const Ref = this._matDialog.open(MyDialogComponent, { data: this.project });
And in the dialog just use as the #Simo said
This will Inject the passed data from component to dialog
constructor(public matDialogRef: MatDialogRef<MyDialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: any) {
console.log(this.data);
}

Data are not showing when two api called in` iondidenter`

I have one screen, which have two gridview . each grid view will populate some value after api calling. so my page will have 2 api calling. so when i call my api call method under constructor or ionViewDidEnter its not working. it allowing only one method to exeute.
here is my two api call method on one page .ts
Even i put under my constructor. But its not showing the data. so if i want to call the both api and need to display the data means how can i do that.please help me out. i was not able to find it out !!
Thanks in advance
updated:
import { Component, ViewChild } from '#angular/core';
import { AlertController, App, FabContainer, ItemSliding, List, ModalController, NavController, ToastController, LoadingController, Refresher } from 'ionic-angular';
import { CategoryDetailPage } from '../categorydetail/categorydetail';
import { ConferenceData } from '../../providers/conference-data';
import { UserData } from '../../providers/user-data';
import { SessionDetailPage } from '../session-detail/session-detail';
import { ScheduleFilterPage } from '../schedule-filter/schedule-filter';
import {Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
import { AuthService } from '../../providers/AuthService';
#Component({
selector: 'page-speaker-list',
templateUrl: 'speaker-list.html'
})
export class SpeakerListPage {
loading: any;
data: any;
Catdata: any;
Catdatanames: any;
resdata: any;
resCatdata: any;
resCatdatanames: any;
loginData: {username?: string} = {};
resloginData: {username?: string} = {};
constructor(
public alertCtrl: AlertController,
public app: App,
public loadingCtrl: LoadingController,
public modalCtrl: ModalController,
public navCtrl: NavController,
public toastCtrl: ToastController,
public confData: ConferenceData,
public user: UserData,
public http:Http,
public authService: AuthService
) {
}
ionViewDidEnter() {
this.show();
this.another();
}
show() {
this.showLoader();
this.authService.subs(this.loginData).then((result) => {
this.loading.dismiss();
this.data = result;
if(this.data.status == 1)
{
this.Catdata = this.data.SubjectList;
//this.Catdata.forEach(category => console.log(category.CatID));
for(let i=0; i<this.Catdata.length; i++) {
// console.log(this.Catdata[i].SubjectName);
}
}
else if(this.data.status == 0) {
let alert = this.alertCtrl.create({
title: 'Error',
subTitle: 'Please Enter Valid Username & Password',
buttons: ['OK']
});
alert.present();
}
}, (err) => {
this.loading.dismiss();
});
}
another() {
this.authService.allresources(this.resloginData).then((result) => {
this.resdata = result;
if(this.resdata.status == 1)
{
this.resCatdata = this.resdata.SubjectList;
for(let i=0; i<this.resCatdata.length; i++) {
// console.log(this.resCatdata[i].FileName);
}
}
else if(this.resdata.status == 0) {
let alert = this.alertCtrl.create({
title: 'Error',
subTitle: 'Please Enter Valid Username & Password',
buttons: ['OK']
});
alert.present();
}
}, (err) => {
});
}
showLoader(){
this.loading = this.loadingCtrl.create({
content: 'Authenticating...'
});
this.loading.present();
}
}

How to get values from JSON webservice with 2 objects in Angular 2

I'm new in Angular 2 and I'm quite lost. I have a JSON web service responding to /rest/alertsDashboard. It returns something like:
{
"total": {
"totalOperations": 2573,
"totalOperationsAlert": 254,
"totalOperationsRisk": 34
},
"alerts": [
{
codAlert: "L1",
description: "Alert 1",
value: 1
},
{
codAlert: "L2",
description: "Alert 2",
value: 2
},
...
]
}
So I defined a DashboardComponent component and a AlertDashboardService service. I would like, for example, to display totalOperations and totalOperationsAlert. I don't know if I'm doing it in a correct way.
In dashboard.component.ts I have:
...
#Component({
selector: 'app-dashboard',
template: `
<p>{{totalAlertsDashboard.totalOperations}}</p>
<p>{{totalAlertsDashboard.totalOperationsAlert}}</p>
...
`
})
export class DashboardComponent implements OnInit {
totalAlertsDashboard: TotalAlertsDashboard;
alertsDashboard: AlertDashboard[];
constructor(private alertsDashboardService: AlertsDashboardService) { }
ngOnInit() {
this.alertsDashboardService.get().then(
response => {
this.totalAlertsDashboard = response.totalAlertsDashboard;
this.alertsDashboard = response.alertsDashboard;
}
);
}
}
In alerts-dashboard.service.ts I have:
...
export class AlertsDashboard {
totalAlertsDashboard: TotalAlertsDashboard;
alertsDashboard: AlertDashboard[];
}
export class TotalAlertsDashboard {
totalOperations: number;
totalOperationsAlert: number;
totalOperationsRisk: number;
}
export class AlertDashboard {
codAlert: string;
description: string;
value: number;
}
#Injectable()
export class AlertsDashboardService {
private headers = new Headers({ 'Content-Type': 'application/json' });
private url = environment.urlAPI + '/rest/alertsDashboard';
constructor(private http: Http) { }
get(): Promise<AlertsDashboard> {
var vm = this;
let params = new URLSearchParams();
return vm.http.get(vm.url, { search: params })
.toPromise()
.then(response => {
var responseJson: AlertsDashboard = response.json() ;
console.log(responseJson); // it prints the JSON correctly
return responseJson;
});
}
}
I hope you can help me with that.
try this :
ngOnInit() {
this.alertsDashboardService.get().then(
response => {
this.totalAlertsDashboard = response.total;
this.alertsDashboard = response.alerts;
}
);
}
In alerts-dashboard.service.ts
export class AlertsDashboard {
total: TotalAlertsDashboard;
alerts: AlertDashboard[];
}
template :
<p>{{totalAlertsDashboard?.totalOperations}}</p>

Angular ignoring JSON fields on Object instantiation

I am trying to query the wagtail API that will return JSON in a very unfriendly format.
{
"id": 3,
"meta": {
"type": "home.HomePage",
"detail_url": "http://localhost:8000/api/v1/pages/3/"
},
"parent": null,
"title": "Homepage",
"body": "<h2>cool an h2 fgf</h2>",
"main_image": {
"id": 1,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "http://localhost:8000/api/v1/images/1/"
}
},
"header_image": {
"id": 1,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "http://localhost:8000/api/v1/images/1/"
}
},
"show_in_menus": true,
"full_url": "/media/images/Background-4.original.jpg"
}
All I really want from that is a class like this.
export class HomePage {
id: number;
title: string;
body: string;
full_url: string;
}
But whenever I get back from the data back from my service and try and log it, it is undefined.
Is there any way for me to ignore the fields I don't want from a JSON in typescript?
The service I am using is:
import { Injectable } from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from "rxjs";
import {HomePage} from "./HomePage";
#Injectable()
export class HomePageService {
constructor(private http: Http){
}
getHomePage(GUID: number): Observable<HomePage>{
return this.http
.get("http://localhost:8000/api/v1/pages/" + GUID + "/")
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {}
}
private handleError (error: Response | any) {
// In a real world app, we might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
And the component:
import {Component, OnInit, OnDestroy} from '#angular/core';
import {HomePageService} from './home-page.service';
import {ActivatedRoute} from '#angular/router';
import {HomePage} from "./HomePage";
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css'],
providers: [HomePageService]
})
export class HomePageComponent implements OnInit, OnDestroy{
id: number;
private sub: any;
public homePage: HomePage;
errorMessage: string;
constructor(private homePageService : HomePageService, private route: ActivatedRoute) {
}
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.id = +params['id'];
});
this.homePageService.getHomePage(this.id)
.subscribe(
homePage => this.homePage = new HomePage(homePage),
error => this.errorMessage = <any>error,
() => console.log(this.homePage.full_url)
);
console.log(this.id);
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
homePage => this.homePage = new HomePage(homePage) - in your code I don't see a constructor defined for HomePage class. So when you pass the homePage object to it, nothing happens. Try this:
export class HomePage{
id: number;
title: string;
body: string;
full_url: string;
constructor(homePageObj: any)
{
if (homePageObj)
{
this.id = homePageObj.id;
this.title = homePageObj.title;
this.body = homePageObj.body;
this.full_url = homePageObj.full_url;
}
}
}