Troubleshooting: Resolving the "Cannot read property '...' of undefined" error in Angular service method within a template

After adding new functions to a service in my project, I encountered an error when trying to call a service function from my component template. The error message displayed was "Cannot read property 'isCompanyEligible' of undefined."

I attempted to create a new function within my component and assign the service function to it, but unfortunately, I faced the same error.

Below is the code for my service:

import { FinancialHealth } from 'src/app/shared/models/financial-health';
import { LocalStoreService } from 'src/app/shared/services/local-store.service';
import {Application} from './../models/application';
import {Injectable} from '@angular/core';
import { NgbDateParserFormatterService} from './ngb-date-parser-formatter.service ';

@Injectable({
  providedIn: 'root'
})

export class EligibilityService {
  application: Application;
  activityAreas = [];
  areasEligibility = [];
  legalForms = [];
  jobPositions = [];
  constructor(
    private ls: LocalStoreService,
    private dateService: NgbDateParserFormatterService

  ) {
    this.application = this.ls.getItem('application');
    const {
      activity_areas,
      legal_forms,
      job_positions,
      areas_eligiblity
    } =
    this.ls.getItem('shared_data').data;
    this.activityAreas = activity_areas;
    this.legalForms = legal_forms;
    this.jobPositions = job_positions.filter(job => job.is_management_position ==
      1);
    this.areasEligibility = areas_eligiblity;
  }

  public isCompanyEligible(application ? ) {
    if (application) {
      this.application = application;
    }
    if (!this.application || (!this.application.company)) {
      return null;
    }
    const company = this.application.company;
    let age;
    if (typeof this.application.company.established_at == 'object') {
      const date =
        this.dateService.format(this.application.company.established_at);
      age = this.getAge(date);
    } else {
      age = this.getAge(company.established_at)
    }
    return this.legalForms.includes(company.legal_form) && (age >= 2 && age <=
      5);
  }

  growthRate(firstYear, secondYear) {
    if (!firstYear || !secondYear) {
      return 0;
    }
    return Math.round(((secondYear - firstYear) / firstYear) * 100);
  }
}

This is my component.ts:

import { Component, OnInit } from '@angular/core';
import { CustomValidators } from 'ng2-validation';
import { FormGroup, FormBuilder, FormControl } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
import { DataLayerService } from 'src/app/shared/services/data-layer.service';
import { BreadcrumbService } from '../../../shared/services/breadcrumb.service';
import { EligibilityService } from 'src/app/shared/services/eligibility.service';

@Component({
  selector: 'app-form-sommaire',
  templateUrl: './sommaire.component.html',
  styleUrls: ['./sommaire.component.scss']
})
export class SommaireFormComponent implements OnInit {
  formBasic: FormGroup;
  loading: boolean;
  radioGroup: FormGroup;
  sharedData: any;
  isValid: Boolean = false;
  application: any;
  breadcrumb: { label: string; route: string; }[];
  title: String = 'Sommaire';
  constructor(
    private fb: FormBuilder,
    private toastr: ToastrService,
    private ls: LocalStoreService,
    private appService: ApplicationService,
    private data: BreadcrumbService,
    public eligibility: EligibilityService
  ) { }

}

This is my HTML template:

<div class="col-lg-2">
  <i *ngIf="eligibility.isCompanyEligible()" class="icon ion-ios-checkmark-circle large-success"></i>
  <i *ngIf="eligibility.isCompanyEligible() === false" class="icon ion-ios-close-circle large-danger"></i>
  <i *ngIf="eligibility.isCompanyEligible() == null" class="icon ion-md-alert large-warning"></i>
</div>

Answer №1

Components marked as private cannot be accessed by their template. (Private members can still be accessed during development with JIT, but not in production with AOT.)

The recommended approach is to encapsulate service properties/methods within a component property/method, and then bind/call that from the template to access the service data.

For example:

get isCompanyEligible(): boolean {
    return this.eligibility.isCompanyEligible();
}

Then use it in your template: -

<i *ngIf="isCompanyEligible()"

OR

To make the EligibilityService injection public in the component's constructor, allowing access inside the template:

constructor(
    private fb: FormBuilder,
    private toastr: ToastrService,
    private ls: LocalStoreService,
    private appService: ApplicationService,
    private data: BreadcrumbService,
    public eligibility: EligibilityService
) { }

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

JavaScript: The initial function call does not correctly switch the "boolean" in Local Storage

I'm currently developing a project that involves implementing a tutorial overlay. My goal is to have the overlay toggle on and off using a button, while also ensuring that the state of the button is remembered between page transitions so that users do ...

Improving the Roman Numeral Kata with JavaScript

As a newcomer to the world of coding, I have taken on the challenge of mastering the Roman Numeral Kata using Javascript. I am pleased to report that all the specifications are passing successfully. After refactoring the spec file, I am now focusing on re ...

In order for Angular forms to be considered valid, they must fall into one of two form

I am attempting to create a dynamic angular form where the user must enter either A or B. A represents a unique identifier, while B consists of a set of values that correspond to that identifier. My goal is to validate the form as valid if either A is ente ...

Angular client encounters error "Access Control Check Fails for Preflight Request" when integrating with ASP.net Core SignalR

In my ASP.Net core server startup.cs file, I have the following code within the ConfigureServices method: services.AddCors(o => o.AddPolicy("CorsPolicy", builder => { builder .AllowAnyMethod() .AllowAnyHeader() ...

"Exploring the power of Vue3's composition API in managing the

Trying to implement an accordion component in Vue 3, but encountering a strange comparison issue. I'm attempting to execute a function within the accordionitem - specifically the toggle operation. However, despite numerous attempts, I am unable to mo ...

Avoiding Maximum Call Stack Size Exceeded in Observables: Tips and Tricks

After filtering, I have a list stored in the variable filteredEvents$: public filteredEvents$ = new BehaviorSubject([]); I also have a method that toggles the checked_export property and updates the list: public checkAll(): void { this.filteredEve ...

"Element UI, featuring a wide array of components, contributing to bloated bundle sizes

I was looking into the following link. After following the instructions, I realized I am using class based components. Therefore, I am importing as shown below: import {Checkbox} from 'element-ui'; @Component({ components: { Checkbox } }) e ...

What is the best way to dynamically select and deselect radio buttons based on a list of values provided by the controller?

I am currently working on implementing an edit functionality. When the user initially selects a list of radio buttons during the create process, I store them in a table as a CSV string. Now, during the edit functionality, I retrieve this list as a CSV stri ...

Retrieving JSON data by key through ajax does not show the expected output

I'm currently working with JSON data in the form of an array, and I'm facing some issues. Here's how the data looks: [ { "id": 1, "name": "Leanne Graham", "username": "Bret", ...

Finding the height of concealed content within a div using the overflow:hidden setup

I'm trying to create a div that expands when clicked to reveal its content. I've taken the following steps so far: Established a div with overflow:hidden property Developed a JavaScript function that switches between a "minimized" and "maximize ...

Transitioning CSS - An elegant way to display div contents

Here's the concept: A hidden div that slides down, pushing other content, when a button is clicked. Clicking the button again will hide the div and raise the other content. HTML <div id="topDiv" class="hidden"> Some content<br> M ...

Is the selected mat-selection-list coming in first place?

Is there a way to display the selected values on top of a mat-selection-list filled with mat-list-option elements? <mat-selection-list formControlName="mySubEntityIds"> <mat-list-option [value]="entity.id" *ngFor="let entity of entities" checkb ...

The parameter type '==="' cannot be assigned to the 'WhereFilterOp' type in this argument

I'm currently working on creating a where clause for a firebase collection reference: this.allItineraries = firebase .firestore() .collection(`itinerary`); Here is the issue with the where clause: return this.allItiner ...

Cannot find a function within the Promise

Here is the code snippet I am working with: var c = function(address, abiJson){ var _ = this; this.data = { wallet: false, account:{ address: false }, contract:{ addre ...

Obtain the leaf nodes from a combination of arrays and objects using Lodash

Here is the code structure I want to share with you before explaining my requirements. It displays the input array layout along with the desired outcome: [ { link: "someurl", name: "Foo", subCats: [ { link: "anotherurl", ...

Imagine you are looking to execute an if/else statement

I'm having some trouble with this code that is meant to print different values based on certain conditions, but it only seems to be printing one value consistently. See the code snippet below: let twitterfollowers; let websitetraffic; let monthlyre ...

Top method for declaring and setting up variables in Angular 2

I've been diving into the Angular Style Guide, but a question has come up: what is the most effective method for initializing a variable in a component? For instance, should I declare a variable like so: export class MyComponent implements OnInit { ...

Modifying an item in a list using React and Redux

I am facing an issue with my table that consists of 50 rows, each representing an item from a list. When I click on a checkbox within a row, I want to mark that specific item as selected. However, the problem is that clicking on any checkbox causes all 50 ...

Is it possible to retrieve the selected DataList object in Angular 10?

I encountered an issue while creating an Input field with DataList. My goal was to retrieve the entire object associated with the selected option, but I could only access the selected value. Previous suggestions mentioned that DataList items should be uniq ...

Equality and inequality in arrays

Could someone help clarify why these comparisons between different JavaScript arrays result in true? ["hello"] !== ["world"] [42] !== [42] ["apple"] != ["orange"] [7] != [7] ...