Angular Typescript subscription value is null even though the template still receives the data

As a newcomer to Angular and Typescript, I've encountered a peculiar issue. When trying to populate a mat-table with values retrieved from a backend API, the data appears empty in my component but suddenly shows up when rendering the template.

Here's an example of my component:


import { Component, OnInit, ViewChild } from '@angular/core';
import { first } from 'rxjs/operators';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, MatSort } from '@angular/material';

import { Invoice } from '../_models';
import { InvoiceService } from '../_services';

@Component({
  selector: 'app-invoices',
  templateUrl: './invoices.component.html',
  styleUrls: ['./invoices.component.css']
})
export class InvoicesComponent implements OnInit {
  displayedColumns=['rating', 'amount', 'debtor', 'serial', 'dateout', 'expiration', 'daysleft', 'fid']
  invoices: Invoice[] = [];
  dataSource= new MatTableDataSource<Invoice>(this.invoices);

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  constructor(
    private invoiceService: InvoiceService
  ) { }

  ngOnInit() {
    this.loadInvoices();
    console.log(this.invoices);
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }
  private loadInvoices(){
    this.invoiceService.getUserInvoices().pipe(first()).subscribe(invoices => {
      this.invoices=invoices;
    });
    console.log(this.invoices);


  }
  applyFilter(filterValue: string) {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
    this.dataSource.filter = filterValue;
    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

}

And here is a snippet from the template:


...

@foreach($invoices as $invoice)
...
@endforeach

...

The key point of concern lies in the usage of [dataSource]="invoices". Upon retrieving data via the loadInvoices method, the array remains empty. Switching it to [dataSource]="dataSource" also results in an empty array. How can I effectively utilize the fetched data to initialize a MatTableDataSource object and pass it to the template?

With assistance from @DiabolicWords, the updated component code looks like this:


// Updated component code

Answer №1

If you're struggling with the timing of values returning from an Observable and your console.log()-calls are firing before the data is actually populated, there's a simple fix to ensure you display the correct information. Give this approach a try:

 ngOnInit() {
   this.loadInvoices();
 }

 private loadInvoices(){
   this.invoiceService.getUserInvoices().pipe(first()).subscribe(invoices => {
     this.invoices=invoices;
     console.log(this.invoices);
     this.dataSource = new MatTableDataSource<Invoice>(this.invoices); 
     this.dataSource.paginator = this.paginator;
     this.dataSource.sort = this.sort;
   });
 }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guaranteeing the sequential execution of JavaScript functions

For weeks, I've been struggling with a program that utilizes ajax post methods and dataTables. It has become clear to me that my understanding of how javascript operates is lacking. Below is the javascript code: $('#SaveTimeSheet').click(fu ...

What is the best way to obtain an error as an object when subscribing to an HTTP GET request

I am working on an asp.net core webApi along with an Angular9 WebApp. My goal is to retrieve the error in a subscribe as an object rather than just a string. this.http.post<TestSystem>(this.url, testsystem).subscribe((result) => { // do someth ...

Select2 eliminates every tag except the first one

I am currently utilizing Select2 in Django for handling many-to-many relationships. The best approach I have found to handle all validation constraints is to create related objects through an AJAX request as soon as they are entered into the Select2 tag fi ...

Instead of relying on Vue TypeScript, we are leveraging IntelliJ with TypeScript 5.0.3 to compile our Vue project

My current version of IntelliJ IDEA is 2023.1 (Ultimate Edition) Build #IU-231.8109.175, released on March 28, 2023. I am facing an issue where my project fails to compile using "Vue TypeScript", resulting in some type mismatches being overlooked. In the ...

I'm seeking guidance on how to delete a specific ul li element by its id after making an ajax request to delete a corresponding row in MySQL database. I'm unsure about the correct placement for the jQuery

I have created an app that displays a list of income items. Each item is contained within an li element with a unique id, along with the item description and a small trash icon. Currently, I have implemented code that triggers an AJAX call when the user cl ...

The navigation menu items remain static until a manual refresh is performed

I am facing an issue with my Angular app's authentication system. The navmenu displays login, logout, and the username when a user is logged in. However, after logging in, the navbar does not update until the page is refreshed. I can't figure out ...

Tips on filtering an array in a JSON response based on certain conditions in Angular 7

Looking to extract a specific array from a JSON response based on mismatched dataIDs and parentDataIDs using TypeScript in Angular 7. { "data":[ { "dataId":"Atlanta", "parentDataId":"America" }, { "dataId":"Newyork", ...

Leverage the power of JSON objects in C# programming

I am receiving a JSON response from this web service. Can you provide guidance on how to use this message as an object in my ASP.NET web application? ...

What is the best way to use AJAX to update multiple items with a common customer number on a SharePoint list?

Currently, I am facing an issue while attempting to update a SharePoint list using JavaScript/ajax. The script is running smoothly until it reaches the ajax function, where it encounters a failure. Specifically, it mentions that the ItemID is not defined, ...

Utilizing FileInterceptor with a websocket in NestJs: A Step-by-Step Guide

Is it possible to implement this on a websocket, and if so, how can I achieve that? @UtilizeInterceptors( DocumentInterceptor('image', { location: '../data/profileImages', restrictions: { size: byte * 10 }, ...

Error: Trying to access the `push` property of an undefined value is causing an issue

Issues with using the push method in TypeScript have arisen. Here are the details: Below is the code snippet for the reservation modal component: guestArray=[1, 2, 3, 4, 5, 6]; guests: number; isDateTime: boolean = false; constructor(private params: Mo ...

JavaScript pop-up purchase tooltips from MenuCool

I am relatively new to the world of web design and programming. I am putting in a lot of effort to learn as much as possible, but I am encountering difficulties with the tooltip JavaScript that I incorporated into my website Click here to visit my website ...

What is the best way to modify the color of a table cell in Typescript with *ngFor loop?

I have an image located at the following link: My goal is to have cells with different colors, where main action=1 results in a green cell and action=0 results in a red cell. Below is the HTML code I am working with: <div class="row" colum> ...

Multiple Ajax calls interacting with each other are causing issues

Within my Index.php file, there is an ajax call that loads a php page containing an HTML form. I am attempting to trigger another ajax call from Index.php whenever a select box is changed. Everything functions properly except for the ajax on change event ...

Searching for a way to access the HTTP request header using ReactJS?

Can anyone assist me in retrieving the request header's cookie? I have searched extensively but haven't found a satisfactory document. Please share with me a reliable solution. ...

Sharing a let value within *ngFor loop from template to .ts file - here's how

Is it possible to use the async pipe to share the interpolation value {{ticketType.name}} with the .ts component in order to work with this value efficiently? Here is a sample of the template code: <mat-option *ngFor="let ticketType of ticketTypes ...

Display JSON information in a grid using JQuery

I'm on the lookout for a simple json grid plugin to make my life easier. I need to populate a grid using JSON/Ajax, but the catch is that the amount of data or columns will vary each time, so it needs to be able to adapt accordingly. For example, a p ...

The design of RESTful web applications with a client-server architecture

I need clarification on how client-server architecture should function for a modern web application with a RESTful backend. For a web app, the client is typically the browser while the server is the web server. Programatically speaking, there are componen ...

When utilizing ng2-bootstrap, there is no directive that is defined with the "exportAs" attribute set to "bs-modal"

I found a tutorial that I am trying to emulate from this website However, when I insert the template into my HTML file <div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}" tabindex="-1" role="dialog" ...

Declaring variables or fields with specific type restrictions

Imagine we have a generic interface: export interface IKeyValue<K, V> { key: K; value: V; } Now, our goal is to define a variable or field and restrict the types that can be used as K and V: public items: IKeyValue<K extends Type1, V ex ...