Issue encountered with Angular app breaking upon reloading, likely due to a lifecycle hook error

My Angular application sends the Firebase user ID to my server, which then responds with an array of objects to be displayed in a data table.

Everything works fine when I navigate to the data table from the default page. However, upon reloading the app, an error occurs stating "Error trying to diff '[object Object]'. Only arrays and iterables are allowed".

I suspect that this error is caused by the response containing an error message that cannot be properly displayed in the table.

The issue seems to arise because upon reloading the page, the user ID is not retrieved, resulting in the parameter sent to the server being undefined and triggering the error.

Therefore, my question is how can I retrieve the user ID when reloading the data table component before sending the request to the server?

Service:

private user: Observable<firebase.User>;
public userDetails: firebase.User = null;
uid: any;

constructor(private http: HttpClient,
            private authFirebase : AngularFireAuth) {
              this.user = authFirebase.authState;
              this.user.subscribe(
                (user) => {
                  if (user) {
                    this.userDetails = user;
                    console.log(this.userDetails.email);
                    this.uid = this.userDetails.uid;
                  }
                  else {
                    this.userDetails = null;
                  }
                }
              );
             }

getFullRegistryUniversity(): Observable<DegreeDetails[]> {
  console.log(`serviceuid: ${this.uid}`);
  let uidString = {
    "uid" : this.uid
  }
  return this.http.post<DegreeDetails[]>(this.serviceUrl, uidString)
}

Component:

export class GraduateComponent implements OnInit {

dataSource = new UserDataSource(this.registryService);
displayedColumns = ['graduateRut', 'major', 'university', 'gradYear'];

constructor(private registryService: RegistryService) { }

ngOnInit() {}

}

export class UserDataSource extends DataSource<any> {
constructor(private registryService: RegistryService) {
  super();
}
connect(): Observable<DegreeDetails[]> {

return this.registryService.getFullRegistryUniversity();
}
disconnect() {}
}

Edit:

HTML:

<div>
<mat-table [dataSource]="dataSource">
  <ng-container matColumnDef="graduateRut">
    <mat-header-cell *matHeaderCellDef> RUT </mat-header-cell>
    <mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.graduateRut}} </mat-cell>
  </ng-container>
  <ng-container matColumnDef="major">
    <mat-header-cell *matHeaderCellDef> E-Mail </mat-header-cell>
    <mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.major}} </mat-cell>
  </ng-container>
  <ng-container matColumnDef="university">
    <mat-header-cell *matHeaderCellDef> University </mat-header-cell>
    <mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.university}} </mat-cell>
  </ng-container>
  <ng-container matColumnDef="gradYear">
    <mat-header-cell *matHeaderCellDef> GradYear </mat-header-cell>
    <mat-cell *matCellDef="let degreeDetails"> {{degreeDetails.gradYear}} </mat-cell>
  </ng-container>
  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>

Answer №1

It seems that the API is being called before the UID has been initialized, resulting in an error. There are several ways to address this issue, but here is one approach to begin with:

uid = new BehaviorSubject<any>(null);

In the constructor:

this.user.subscribe(
  (user) => {
    if (user) {
      this.userDetails = user;
      console.log(this.userDetails.email);
      this.uid.next(this.userDetails.uid);
    }
    else {
      this.userDetails = null;
    }
  }
);

Update the http post request to utilize the BehaviorSubject:

getFullRegistryUniversity(): Observable<DegreeDetails[]> {
    let uidString = {
      "uid" : this.uid.value // <-- here
    }
    return this.http.post<DegreeDetails[]>(this.serviceUrl, uidString)
  }

Add a get method:

getUidObservable() {
 return this.uid.asObservable()
}

In your component, wait for the UID to have a valid value before initializing the datasource:

dataSource: UserDataSource;

ngOnInit() {
 this.registryService.getUidObservable().subscribe(_uid => {
  if(_uid !== null) {
     dataSource = new UserDataSource(this.registryService);
   }
 }
}

Lastly, in your html, add the following to the wrapping div:

<div *ngIf="dataSource">

This approach should help resolve the issue and ensure secure calls. It may not be the fastest solution, but it can stabilize your requests.

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

Unlock the tab element within a modal using ng-bootstrap

I am currently encountering an issue with ng-bootstrap in Angular 2. I am unable to access the #tabs variable from my component using @ViewChild. This problem arises only when I utilize the tab directive within the modal directive. Here is a snippet of m ...

Efficiently import all files within a folder using TypeScript

While working with NodeJS and TypeScript, the process of requiring files is slightly different. Check out the example below: const fs = require('fs') fs.readDirSync('/dir/name') .forEach(dir => require(dir)) How can I achieve the s ...

Information about the HTML detail element in Angular 2 is provided

Hi, I'm curious if there's a way to know if the details section is open or closed. When using <details (click)="changeWrap($event)">, I can't find any information in $event about the status of the details being open. I am currently wor ...

What is the reason behind TypeScript's Omit function not validating the values of the properties that are omitted?

Context: (optional) I was experimenting with ways to enhance the usability of the update(person: Person) function by allowing only a subset of properties to be updated. I considered two options: Passing the id explicitly as the first argument to the upda ...

Strategies for resolving type issues in NextJs with Typescript

In my project using Next.js with TypeScript, I encountered an issue while trying to utilize the skipLibCheck = false property for enhanced checking. This additional check caused the build process to break, resulting in the following error: Error info - U ...

Typing slowly in Angular's modal window

Recently, I encountered an issue with a modal window that contained a text input. Whenever I tried typing in the text input field, it was incredibly slow. Strangely, this text input did not have any events attached to it apart from ngModel. A screenshot fr ...

What is the process for performing type checking on an array variable designated as "as const"?

Check out this code snippet: export type Types = 'a' | 'b'; export type MyPartials = { readonly [P in keyof Types]?: number; }; export interface MyI { readonly name: string; readonly myPartials: MyPartials; } export const myI ...

What is preventing Ionic from locating my model interface?

I recently started working with Ionic and I am using a tutorial as a guide to integrate Firebase authentication into my project. However, I am encountering an issue with the user interface that is being generated. When I run ionic serve for the first time ...

Is there a way to prevent the ng2-bootstrap datepicker div from being displayed when the user clicks outside of it?

I'm utilizing an ng2-datepicker to collect a user's date of birth during the registration process. To adhere to the requirement of displaying it as a popup, I have enclosed the datepicker within a div that is displayed when the user clicks a butt ...

Is it possible to consistently show the placeholder in mat-select regardless of the item currently selected?

I am looking to keep the mat-select element displaying the placeholder at all times, even if an option has been selected. Below is my HTML code: <mat-select [formControlName]="'language'" placeholder="Language"> <mat-option value=" ...

The module '@angular/cdk/clipboard' cannot be located at this time

I recently encountered an error after installing Angular Material in my project. Here is a snippet from my package.json file. I am using Angular 8 and have attempted to modify the versions of Angular Material components. "dependencies": { & ...

Encountering an unknown error with lite server when running npm start

A few weeks back, I was working on an Angular2 project and left it as is in the cloud. However, now when I try to run the project, I encounter an error right from the start. I suspect that the issue lies with lite-server, even though I have updated the no ...

When working with Typescript and React, you may encounter an issue where an element implicitly has an 'any' type because the type 'State' has no index signature. This can lead to

In my current mini project, I am using Typescript and React. As someone new to Typescript, I am currently in the process of learning it. Within the project, I have a state defined as follows: type State = { field1: string, field2: string, field3: n ...

Unable to locate a differ that supports the object '[object Object]' of type 'object'. NgFor is restricted to binding with Iterables like Arrays. Unfortunately, there is no current solution available for this issue

I'm encountering a minor issue with my code. I have two HTTP requests and after combining the data from both, I encounter an error when trying to loop through the final array. I've read other posts suggesting that the returned object is not an a ...

Verify whether the message received contains a specific text within the property

Currently, I am facing a challenge with displaying a specific div in my component template only if any incoming messages contain the TYPE_OTHER property. With numerous variations of the TYPE_OTHER identifier, I am pondering on creating a condition that can ...

Trouble with the edit icon not appearing on ag-grid

Software Version: Angular: 10.0.10 @angular/cli 10.0.6 To add Bootstrap, I used the following commands npm install @coreui/angular --save npm install bootstrap Check out the code below: app.module.ts @NgModule({ bootstra ...

The name 'Map' cannot be located. Is it necessary to alter your target library?

After running the command tsc app.ts, an error occurs showing: Error TS2583: 'Map' is not recognized. Should the target library be changed? Consider updating the lib compiler option to es2015 or newer. I want the code to compile without any issu ...

"During pouchdb testing, we observed the syncing state being emitted while simulating a remote

This Angular 2 application includes Jasmine for testing. I have a function that initiates syncing with the remote DB (from Couchbase to PouchDB only). Various services subscribe to an observable that is triggered on the replication event. I am now tasked w ...

Unable to retrieve URL for locally uploaded image?

Currently, I am utilizing the React Grid Gallery to showcase images on one of my web pages. Everything works smoothly when displaying already uploaded images pulled from my database. However, I'm encountering an issue when trying to preview newly upl ...

The specified starting point "@angular/material/card" cannot be accessed due to missing dependencies

When attempting to deploy a web application on Heroku, I encountered the following error message: - Generating browser application bundles (phase: setup)... Compiling @angular/core : es2015 as esm2015 Compiling @angular/common : es2015 as esm2015 Compiling ...