The angular2 error message indicating a property cannot be read if it is

Encountering an issue trying to utilize a method within an angular2 component. Here's the code snippet :

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AgGridModule } from 'ag-grid-angular/main';
import { GridOptions, GridApi, ColumnApi } from "ag-grid";

import { AllService } from './all.service';
import { SomeClass } from './someClass';
import { ResponseData, Links } from './response';

import 'rxjs/Rx';

@Component({
  selector: 'all',
  styleUrls: ['./all.scss'],
  templateUrl: './all.html'
})

export class AllComponent implements OnInit {

  embedded: Array<SomeClass>
  page: number;
  page_count: number;
  link: Array<Links> = [];
  total_items: number;
  page_size: number;
  private gridOptions: GridOptions = {
      enableFilter: true,
      enableSorting: true,
      //pagination: true,
      enableColResize: true,
      animateRows: true
  };
  private api: GridApi;
  private columnApi: ColumnApi;
  private json : JSON;
  private test : String;
  private n : number = 0;

  constructor (private service: AllService, private router: Router) {

  }

  ngOnInit(){
      this.getData();
  }

  private myRowClickedHandler(event) {
      this.goToDetail(event.data.uuid);
  }

  private getData(){
    this.service.getInitData().subscribe(data => {  
      this.embedded = data._embedded.some_class;
      this.page = data.page;
      this.page_count = data.page_count;
      this.page_size = data.page_size;
      this.total_items = data.total_items;
      this.link[0] = data._links;
      this.createGrid();

      this.gridOptions.api.addEventListener('rowClicked', this.myRowClickedHandler);
    });
  }

  private createGrid(){
      this.n = this.embedded.length;
      this.gridOptions.columnApi.autoSizeColumns;
      this.gridOptions.api.setColumnDefs(this.createColumnDefs());
      this.gridOptions.api.setRowData(this.createRows());
      this.gridOptions.api.sizeColumnsToFit();
  }

  private createRows(){

      var rowData:any[] = [];

      var regexp1 = /[a-zA-Z0-9]*$/;

      for (var i = 0; i < this.n; i++) {

          rowData.push({
              uuid: this.embedded[i].uuid,
              state: this.embedded[i].state,
              executionDate: this.embedded[i].executionDate,
              startDate: this.embedded[i].startDate,
              endDate: this.embedded[i].endDate,
              taskClass: regexp1.exec(this.embedded[i].taskClass)[0],
              humanDuration: this.embedded[i].humanDuration,
              humanMemoryConsumption: this.embedded[i].humanMemoryConsumption,
          });
      }

      return rowData;

  }

  private createColumnDefs() {
      return [
        {headerName: 'uuid', field: 'uuid'},
        {headerName: 'state', field: 'state', filter: 'text', cellStyle: function(params) {
            switch(params.value){
                case "STATE1": return {color: 'orange'};
                case "STATE23": return {color: 'green'};
                case "STATE8": return {color: 'red'};
            }
        }},
        {headerName: 'executionDate', field: 'executionDate'},
        {headerName: 'startDate', field: 'startDate'},
        {headerName: 'endDate', field: 'endDate'},
        {headerName: 'taskClass', field: 'taskClass'},
        {headerName: 'humanDuration', field: 'humanDuration'},
        {headerName: 'humanMemoryConsumption', field: 'humanMemoryConsumption'},
        {headerName: 'action', field: 'action'}
      ]
  }

  public goToDetail(uuid: String) {
      let link = ['pages/all', uuid];
      this.router.navigate(link);
  }
 }

Encountering an error message as below :

EXCEPTION: Cannot read property 'goToDetail' of undefined

Unclear on the root cause of this issue... Could the problem be linked to the subscribe method?

Answer №1

Perhaps you could experiment with utilizing the Function.prototype.bind() method. This approach allows you to explicitly define the value to serve as this when the callback function is executed.

Here is an example of how you could implement it:

this.gridOptions.api.addEventListener('rowClicked', this.myRowClickedHandler.bind(this), false);

If you neglect to specify a specific value to be used as this, the reference to this inside the handler will default to the element itself, resulting in a potentially undefined outcome.

Answer №2

When the event rowClicked is triggered, the context of this in

this.goToDetail(event.data.uuid);
might not be what you expect. The way it's written may lead you to believe that it's being executed from the AllComponent class, but in reality, it's wherever your event listener is invoked from. At runtime, this does not necessarily refer to your class.

Tobold's recommendation is one solution, but you could also consider using a 'fat arrow' function:

private myRowClickedHandler = (event) => {
    this.goToDetail(event.data.uuid);
}

By using the myRowClickedHandler function with a fat arrow, the context of this will always be correct.

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

The Material UI library is signaling that there is an unidentified property called `selectable` being used with the <table> tag

Whenever I try to add the selectable attribute to the Table component in Material-UI using React JS, I encounter an error. Despite checking that selectable is indeed included in TableProps, the issue persists. List of Dependencies : "material-ui": "1.0.0 ...

"Exploring the world of Node.js with Three.js: A comprehensive guide

In our Node.js class, we've kicked off our exploration of this technology with an interesting assignment. The task is to delve into a chosen Node.js module, grasp the fundamentals, and showcase it to the rest of the class. As I was scouring through li ...

Looking to preserve the "ALL" selection in a JavaScript-CSS filter?

On the front page, there are approximately 16 posts displayed along with a filter featuring 4 drop-down menus showcasing post categories. I have assigned category names as classes to each post div and am currently using javascript to hide them. The code s ...

Hovering into Transition Time

My article card has a transition on the top attribute of the info div, which is supposed to be smooth and last for 0.3 seconds. However, the description suddenly appears during this transition. I'm trying to figure out why this is happening and how to ...

What is the reason behind TypeScript failing to provide type safety in a generic higher order component which introduces extra properties into React components?

I'm currently working on developing a versatile higher order component, but have encountered an issue with type safety not being enforced. Interestingly, when attempting the same implementation without using generics, the type safety is verified as ex ...

"Performing a MongoDB Node query within the time frame of 1 hour from

I am having trouble retrieving data with my query to find all objects within the last hour based on timestamps: Here is the schema I am using: var visitSchema = mongoose.Schema({ timestamp: { type: Date, default: Date.now }, userID: String, userName ...

React: Avoid unnecessary re-rendering of child components caused by a bloated tree structure

I am dealing with a tree/directory structured data containing approximately 14k nodes. The issue I am facing is that every time a node is expanded or minimized by clicking a button, causing it to be added to an 'expanded' Set in the Redux state, ...

Sharing data with external domains and retrieving HTML output using JavaScript

When a browser sends a POST request and expects an HTML page result from JavaScript, problems arise if there is no Access-Control-Allow-Origin in the server response. Unfortunately, changing anything on the server side is not an option. If a human clicks ...

The Express.js server seems to be having trouble rendering a static JavaScript file

Currently, I am in the process of constructing a website and have implemented an express.js server to collect data submitted through a form. Prior to configuring the server, I had already developed the site using static js and css files. Once the connectio ...

What is the best way to transfer files (html, js, css, and resources) while utilizing socket.io?

I am currently in the process of developing a web application that involves the server updating the HTML content on the browser page at specific time intervals, essentially creating an HTML slideshow. My project directory structure is as follows: project ...

Challenges with asynchronous form groups in Angular: comparison between Edge and Chrome

I've set up a FormGroup where certain fields need to be disabled or enabled based on whether a checkbox is checked or not. Initially, my code was working fine, but I encountered an issue when testing it on Microsoft Edge (only previously tested on Chr ...

tips for effectively utilizing getters in array sorting operations

I've been encountering some issues with vuex getters. My objective is to arrange the cart data, which consists of an array of objects, by date using the getter named myCartItems. The problem I'm facing is that when I add a second payload {prod_ ...

How can I retrieve the name of a constant enum member in TypeScript as a string?

Consider the following const enum declaration: const enum Snack { Apple = 0, Banana = 1, Orange = 2, Other = 3 } Is it possible in TypeScript to retrieve the string representation of a specific member? In C#, this could be achieved with ...

Vuetify's paginated server-side datatable does not support client-side sorting

The Challenge The issue I am facing revolves around using a server-side paginated datatable. Specifically, when utilizing the Vuetify data tables component and attempting to perform client-side sorting due to using a public API that I did not develop, the ...

Pairing strings with arrays

I'm trying to compare elements in two arrays and see if there are any matches. However, I can't seem to get it working correctly. let name; let list = ["Kat", "Jane", "Jack"]; // sample array let input = ["Hey", "i'm", "Jack"]; if (input.fo ...

"Access to root is necessary for Angular-cli to run smoothly

After installing angular-cli with the command npm install -g angular-cli, I encountered an error every time I attempted to run any ng command. The error message stated: Error: EACCES: permission denied, open '/home/m041/.config/configstore/ember-cli. ...

Error encountered during the production build of Angular 2. No issues reported during development phase

During development, I can successfully run the code below. However, when I deploy to production, I encounter the following errors: node_modules/@angular/common/src/pipes/async_pipe.d.ts(39,38): error TS2304: Cannot find name 'Promise'. node_modu ...

Saving a revised JSON file using AngularJS

Currently, I am in the process of developing a phonegap application using AngularJS that relies on a .json file to store an array of entries. The main goal I am aiming for is to enable users to mark specific entries as favorites and then utilize that data ...

Implementing a transition effect to the drawimage function

I am currently working on implementing a transition effect for an image inside a canvas element. I have provided a snippet below to demonstrate my progress so far. Can anyone guide me on how to incorporate a transition animation for the image within the c ...

Ways to minimize renders while toggling a checkbox

I'm currently working on developing a high-performance checkbox tree component. To manage the checked checkboxes, I am utilizing a parent level state that contains an array of selected checkbox IDs => const [selected, setSelected] = useState([]); ...