Error in IONIC 4: Unable to retrieve property 'get' as it is undefined

I am attempting to retrieve data from the database using the get() function, but I keep encountering an error with the title:

at HomeTabPage.push ../src/app/home-tab/home-tab.page.ts.HomeTabPage.ngOnInit (home-tab.page.ts: 18)

Even after trying to use the Elvis operator with *ngFor, I still cannot get it to work. I have moved my main function out of ngOnInit and created a new function for reference, but that also did not solve the issue.


home-tab.page.html


<ion-list >
    <ion-item *ngFor="let advert of advertList">
        <ion-thumbnail slot="start">
           <ion-img src="advert?.image"></ion-img>
         </ion-thumbnail>
         <ion-label>
           <h2 >{{advert?.name}}</h2>
           <h3 >{{advert?.price}}</h3>
           <p >{{advert?.description}}</p>
        </ion-label>
     </ion-item>
  </ion-list>

home-tab.page.ts


export class HomeTabPage implements OnInit {
  public advertList: Array<any>;

  constructor(private navCtrl: NavController, public adService: AdvertisingService) {}

  ngOnInit(){
    this.adService.getAdAllList().get().then(advertListSnapshot => {
      this.advertList = [];
      advertListSnapshot.forEach(snap =>{
        this.advertList.push({
          id: snap.id,
          name: snap.data().name,
          price: snap.data().price,
          description: snap.data().description,
          image: snap.data().picture
        });
      });
    });
  }
}

service.ts


export class AdvertisingService {
  public adAllListRef: firebase.firestore.CollectionReference;
  constructor() {
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.adAllListRef = firebase.firestore().collection(`/adverts/adAll/adList`);
      }
    });
  }

  //cRud -> Read
  getAdAllList(): firebase.firestore.CollectionReference {
    return this.adAllListRef;
  }
}

ERROR

HomeTabPage_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property 'get' of undefined
    at HomeTabPage.push../src/app/home-tab/home-tab.page.ts.HomeTabPage.ngOnInit (home-tab.page.ts:18)
    at checkAndUpdateDirectiveInline (core.js:22099)
    at checkAndUpdateNodeInline (core.js:23363)
    at checkAndUpdateNode (core.js:23325)
    at debugCheckAndUpdateNode (core.js:23959)
    at debugCheckDirectivesFn (core.js:23919)
    at Object.eval [as updateDirectives] (HomeTabPage_Host.ngfactory.js? [sm]:1)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)
    at checkAndUpdateView (core.js:23307)
    at callViewAction (core.js:23548)

ERROR

Answer №1

Hey, there's a specific scenario that your current code doesn't handle. What if user is undefined in the function

firebase.auth().onAuthStateChanged
? In such a situation, your this.adAllListRef won't get initialized, leading to the same error occurring.

I may not have a ready-to-use code solution for you, but I can guide you on how to tackle this issue:

Given that this page functions properly only when user is valid, consider implementing an AuthGuard, similar to the following example:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, Route } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private _router: Router,private _advSvc: AdvertisingService) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> 
  {
    return new Promise((resolve) => {
      firebase.auth().onAuthStateChanged(user => {
         if (user) {
            resolve(true);
         } else{
           this._router.navigate(['/login']);
           resolve(false);
         }
      });
   }
}

In the AdvertisingService, you won't need to check for user because it will only be accessed after validation by the AuthGuard.

export class AdvertisingService {
  constructor() {
  }

  getAdAllList(): firebase.firestore.CollectionReference {
    return firebase.firestore().collection(`/adverts/adAll/adList`);
  }
}

Make sure to define the router as follows:

  const route = [
    { .... },
    {path: '/home',component: HomeTabPage, canActivate: [AuthGuard] },
    {path: '/login',component: LoginPage }
  ]

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

What could be causing the callback function to malfunction when setting markers in the Leaflet library for Android?

For my application, I am utilizing the Leaflet library to display maps and draw shapes. The issue I am facing is related to setting markers on the map. While the markers are being set correctly, clicking on them does not trigger the callback function as ex ...

Creating a TypeScript definition file that exports a class after instantiation

Currently, I am struggling with a specific typescript definition that is not functioning as expected: mapping.ts class Mapping { // } var mapping = new Mapping(); export = mapping; This setup allows for the following usage: import _mapping = require(&ap ...

JavaScript => Compare elements in an array based on their respective dates

I have an array consisting of more than 50 objects. This array is created by concatenating two arrays together. Each object in this array contains a 'date' key with the date string formatted as: `"2017-03-31T11:30:00.000Z"` Additionally, there ...

Storing geolocation information in local variables for future use

I am completely new to Nativescript (with Angular 2/TypeScript). My goal is to utilize the Nativescript geolocation plugin to track a user's location and store the data (latitude and longitude) for future use. Here is a snippet of my code: export cla ...

Angular: Inject all dependencies into a component's class

I'm curious about how to supply an injectable class in Angular (4+) that includes all of its dependencies. For example: If we have an injectable called DepMaster, which has dependencies such as: DepServantA DepServantB Simply providing DepMaster a ...

Assigning dynamic key value pairs in Angular 4 using Typescript

I'm currently attempting to construct an object using keys that are specified in an environment file, meaning the keys would vary depending on the environment. import { environment } from '../environments/environment' export abstract class ...

Angular 4 scatter chart with multiple data points using Google charts

I'm currently developing a scatter graph in Angular 4 using ng2-google-charts from https://www.npmjs.com/package/ng2-google-charts It seems like this is essentially a wrapper for Google Chart Service. The graph looks great with a few values, but whe ...

Is there a TypeScript alternative to triggering a click event on a specific class using $(".class").click()?

I am currently utilizing a date range picker within an Angular project. <button type="button" class="btn btn-danger daterange-ranges"> <i class="icon-calendar22 position-left"></i> <span></span> <b class="caret"></b ...

Function cannot be invoked within FB.api() in Angular framework

I'm struggling with implementing the Facebook API in my Angular 6 project. Specifically, I am unable to modify or access the value of a variable inside the FB.api function. My goal is to update the form fields with information retrieved from Facebook ...

Typescript - neglecting a package that lacks typings

I am considering using an open source package that does not have TypeScript bindings. After checking the linked resource, I was unable to find a solution. Although I attempted to use @ts-ignore, it did not function as expected. Could someone please prov ...

The click event in an Angular 6 loop is not being activated

When the Test is clicked, the function should be invoked. However, nothing happens when I click on it. Here is the HTML component code: <div class="row m-0 justify-content-between" *ngFor="let i of k[currentk]?.details | keys"> <div (click ...

How can Angular be used to retrieve JSON data from a server-side PHP file?

I've been utilizing pure javascript to fetch data from php scripts on the server-side, but I'm interested in exploring how to achieve the same with angular. The current code retrieves a php file that executes a simple select query on a database ...

Set the default value for a form control in a select dropdown using Angular

I've been struggling to figure out how to mark an option as selected in my select element, but I haven't had any luck. I've tried multiple solutions from the internet, but none of them seem to be working for me. Does anyone out there have ...

Inhibit unselected choices when a user exceeds choosing a certain number of options

I want users to be able to select a maximum of 3 options from a list. If a form has four options, once the user selects three, the fourth should become disabled. Here is the setup I have: import { Component, Input, ViewChild, OnInit, AfterViewI ...

Dealing with extensive fixtures in Cypress

Scenario: Currently, the task at hand involves setting up end-to-end tests for a web application that relies on a rather complex API. In order to test just one aspect of the site, approximately 15 REST requests need to be intercepted. The API in question ...

How can I set up the default keyboard control for Google's Model Viewer?

Trying to enhance accessibility, I am working on enabling the camera orbit of my model viewer using arrow keys immediately after dismissing the poster. The challenge is that currently, I can only control the camera with arrow keys after interacting with th ...

What is the best way to combine async/await with a custom Promise class implementation?

I've created a unique Promise class. How can I incorporate it with async/await? type Resolve<T> = (x: T | PromiseLike<T>) => void type Reject = (reason?: any) => void class CustomizedPromise<T> extends Promise<T> { ...

Ways to limit the type based on the value of the argument

Is it possible to narrow down the type of the library in the demo code provided? Can we use the factory function to create a new function fnP with an exact type instead of any? const libOne = { p: () => 0, q: () => 1, }; const libTwo = { x: ( ...

Utilizing proxies and leveraging the power of the Map collection in tandem

I have been exploring the Map collection and came across the [[MapData]] internal slot, which led me to utilize Reflect for trapping purposes. After some trial and error, I came up with the following code snippet: const map = new Map(); const proxiedMap ...

What is the best way to trigger a Redux Toolkit action within a React Router DOM action?

My router setup looks like this: const router = createBrowserRouter([ { path: "/", element: <MainLayout />, errorElement: <Error />, children: [ { path: "/inventory", element: <Inve ...