Reputation: 43
So i have this dashboard page with charts and some cards with data. The function to retrieve the data is in ngOnInit() but the problem is that when the page is loaded, the data shows 0. If i click on the chart or something, then the data loads in. Is there anyway to make it straightaway fetch data upon page load? I tried setting a boolean where it will turn true at the end of nginit but it still doesnt work.
<div *ngIf="isLoaded">
Page here
</div>
This is the ts file.
export class DashboardAgentComponent implements OnInit {
totalAssigned=0;
totalAssignedHigh=0;
totalAssignedMed=0;
totalAssignedLow=0;
totalPending=0;
totalPendingHigh=0;
totalPendingMed=0;
totalPendingLow=0;
totalUnassigned=0;
public allTags$ = new BehaviorSubject<Tag[]>([]);
public threeDaysPending = 0;
public sevenDaysPending =0;
public fourteenDaysPending = 0;
public threeDaysAssigned = 0;
public sevenDaysAssigned =0;
public fourteenDaysAssigned = 0;
public isLoaded : boolean = false;
ngOnInit() :void{
this.getTotalAssigned();
}
public trackByFn = (i: number, tag: Tag) => tag.id;
getTotalAssigned()
{
this.mailboxTags.getTotalPending().subscribe((tags: Tag[]) => {
console.log(tags);
// this.allTags$.next(tags);
for (let index = 0; index < tags.length; index++) {
if(tags[index].name == 'pending' && tags[index].type=='view')
{
this.totalPending = tags[index].tickets_count;
}
else if(tags[index].name == 'unassigned')
{
this.totalUnassigned = tags[index].tickets_count;
}
else if(tags[index].name == 'assigned'&& tags[index].type=='view')
{
this.totalAssigned = tags[index].tickets_count;
}
}
});
this.getPendingTickets();
}
getPendingTickets()
{
this.mailboxTags.getPendingHighTickets().subscribe((res: any) => {
let currentDate: any = new Date();
for (let index = 0; index < res.pagination.data.length; index++) {
if(res.pagination.data[index].status=="pending")
{
let createdDate: any = new Date(res.pagination.data[index].created_at);
var diffDays:any = Math.floor((currentDate - createdDate) / (1000 * 60 * 60 * 24));
if(diffDays>3 && diffDays<7)
{
this.threeDaysPending++;
}
else if(diffDays>=7 && diffDays<14)
{
this.sevenDaysPending++;
}
else if(diffDays>=14)
{
this.fourteenDaysPending++;
}
}
}
for (let index = 0; index < res.pagination.data.length; index++) {
if(res.pagination.data[index].status=="assigned")
{
let createdDate: any = new Date(res.pagination.data[index].created_at);
var diffDays:any = Math.floor((currentDate - createdDate) / (1000 * 60 * 60 * 24));
if(diffDays>3 && diffDays<7)
{
this.threeDaysAssigned++;
}
else if(diffDays>=7 && diffDays<14)
{
this.sevenDaysAssigned++;
}
else if(diffDays>=14)
{
this.fourteenDaysAssigned++;
}
}
}
this.isLoaded = true;
});
}
constructor(private breakpointObserver: BreakpointObserver, public mailboxTags: MailboxTagsService) {}
}
Basically all the data that will be used is in the ngOnInit functions.
This is the html. It's not complete but the others are similar.
<div class="grid-container" *ngIf="isLoaded == true">
<h1 class="mat-h1">Dashboard</h1>
<mat-grid-list cols="3" rowHeight="550px" colWidth="100px">
<mat-grid-tile class="grid-tile" [colspan]="1" [rowspan]="1">
<ng-container >
<mat-card class="dashboard-card" >
<mat-card-header>
<mat-card-title>
Unassigned
<button mat-icon-button class="more-button"
[matMenuTriggerFor]="menu" aria-label="Toggle menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu" xPosition="before">
<button mat-menu-item>Expand</button>
<button mat-menu-item>Remove</button>
</mat-menu>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div>{{totalUnassigned}}</div>
</mat-card-content>
</mat-card>
</ng-container>
</mat-grid-tile>
</mat-grid-list>
</div>
So the totalUnassigned is 0 unless i open my matmenu then the data gets updated.
Upvotes: 0
Views: 3066
Reputation: 43
I've solved it by using Angular Resolvers. The ngIf method alone wasnt working for some reason. Here's my updated code:
constructor(private breakpointObserver: BreakpointObserver, public mailboxTags: MailboxTagsService, private _route: ActivatedRoute) {
this.respond = this._route.snapshot.data['tickets'];
this.tag =this._route.snapshot.data['tag'];
this.userID = this._route.snapshot.data['id'];
let currentDate: any = new Date();
for (let index = 0; index < this.respond.pagination.data.length; index++) {
if(this.respond.pagination.data[index].assigned_to == this.userID)
{
if(this.respond.pagination.data[index].status=="pending")
{
let createdDate: any = new Date(this.respond.pagination.data[index].created_at);
var diffDays:any = Math.floor((currentDate - createdDate) / (1000 * 60 * 60 * 24));
if(diffDays>3 && diffDays<7)
{
this.threeDaysPending++;
}
else if(diffDays>=7 && diffDays<14)
{
this.sevenDaysPending++;
}
else if(diffDays>=14)
{
this.fourteenDaysPending++;
}
}
}
}
for (let index = 0; index < this.respond.pagination.data.length; index++) {
if(this.respond.pagination.data[index].assigned_to == this.userID){
if(this.respond.pagination.data[index].status=="assigned")
{
let createdDate: any = new Date(this.respond.pagination.data[index].created_at);
var diffDays:any = Math.floor((currentDate - createdDate) / (1000 * 60 * 60 * 24));
if(diffDays>3 && diffDays<7)
{
this.threeDaysAssigned++;
}
else if(diffDays>=7 && diffDays<14)
{
this.sevenDaysAssigned++;
}
else if(diffDays>=14)
{
this.fourteenDaysAssigned++;
}
}
}
}
for (let index = 0; index < this.tag.length; index++) {
if(this.tag[index].name == 'pending' && this.tag[index].type=='view')
{
this.totalPending = this.tag[index].tickets_count;
}
else if(this.tag[index].name == 'unassigned')
{
this.totalUnassigned = this.tag[index].tickets_count;
}
else if(this.tag[index].name == 'assigned'&& this.tag[index].type=='view')
{
this.totalAssigned = this.tag[index].tickets_count;
}
}
this.isLoaded=true;
}
Upvotes: 0
Reputation: 19073
I tried setting a boolean where it will turn true at the end of nginit but it still doesnt work.
You must not set the isLoaded=true
at the end of ngOnInit()
. This does not ensure that all data have been successfully loaded.
I am pretty sure you miss the basics of asynchronous programming where you must make any changes inside the callback function that get's called.
ngOnInit() {
...
..asynchronousCall...
...
this.isLoaded=true
}
Above scenario won't work.
ngOnInit() {
...
..asynchronousCall.subscribe( e => {
this.isLoaded=true
});
...
}
Above scenario will work because the boolean will be updated when the asyncrhonous call back function get's executed and data has been successfully fetched from the backend
Edit: After you posted all the code my first estimation for your error was correct.
You can solve this by
moving the method invocation this.getPendingTickets();
inside the subscription of getTotalAssigned()
. This way the pending tickets would be fetched only when the totalAsigned tickets have been fetched.
Also move the this.isLoaded = true;
inside the subscription of getPendingTickets()
After you refactor your code like this you will achieve that this.isLoaded
turns true only when TotalAsigned has been fetched and pendingTickets have been fetched.
Upvotes: 1