Struggling to access the 'payload' property of an undefined object? In TypeScript, you can easily bind and access JSON objects using *ngFor directive

I've been attempting to retrieve highscores from the server using node angular and making an http request.

Although I successfully obtain the JSON file from the server, I am encountering difficulty accessing the fields for processing in the *ngFor loop.

The error message I receive specifically relates to the property 'payload':

core.umd.js:3472 EXCEPTION: Error in ./ScoreListComponent class      ScoreListComponent - inline template:18:5 caused by: Cannot read property 'payload' of undefined

Interestingly, it works when using normal javascript in the browser's dev console but not when using the TypeScript variant of it.

import { Component, Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { FormsModule } from '@angular/forms';
import 'rxjs/add/operator/map';

import { ScoreService } from './score.service';

@Component({
  selector: 'scoreList',
  template: `
      <h2>High Scores</h2>
      <table class="table table-striped">
        <thead>
         <tr>
           <th>Rank</th>
           <th>Name</th>
           <th>Score</th>
         </tr>
       </thead>
       <tbody>
         <tr *ngFor="let score of scoreList; let rank = index">
           <td>{{rank + 1}}</td>
           <td>{{score.name}}</td>
           <td>{{score.score}}</td>
         </tr>
       </tbody>
     </table>
     <button
       type="button"
       class="btn btn-success"
       (click)="refresh()">
         refresh
     </button>
      `,
      providers: [ ScoreService ]
})

Furthermore:

@Injectable()
export class ScoreListComponent {

  scoreList = [];

  constructor(private scoreService: ScoreService) { }

  getScores() {
    return this.scoreService.getScores();
  }

  refresh() {
    console.log('refresh, implement a server refresh method')

    this.getScores().map(response => response.json()).subscribe(
      response => this.scoreList.push(response)
    )
    console.log(this)
      console.log(this.scoreList);
      let temp = []
      temp = this.scoreList
      console.log(temp[0].payload.scores)
      //console.log(this.scoreList.entries())

    for(let entry of this.scoreList.entries()){
      console.log(entry);
    }
  }

}
  /* API
  scoreList = [
    { name: "Tom", score: 26, timeStamp: "2016-12-30T10:45:41.062Z" },
    { name: "Joe", score: 23, timeStamp: "2016-12-30T10:45:33.916Z" },
  ];
*/

This is the JSON object we receive from the server:

https://i.sstatic.net/LRnBz.png
(source: xrmb2.net)

If you have any suggestions on how to access the Objects in the Scores Array of the Payload via TypeScript commands, please share!

Answer №1

this.scorelist[0] may not be defined immediately when trying to access it. It is important to wait for the http call to complete before attempting to access it.

  update() {
    console.log('Updating, please wait for server response')
    this.fetchData()
    .map(response => response.json())
    .subscribe((response) =>{
        this.dataList.push(response)
        // Now it should be defined
        console.log(this.dataList[0].payload.data)
        for(let value of this.dataList.values()){
          console.log(value);
        }
      }
    );
    // Trying to access it here will throw an exception as the http call may not have finished
    console.log(this.dataList[0]); // <- This could cause an error
  }

Answer №2

To clarify, it is not necessary to include the @Injectable decorator prior to defining ScoreListComponent. Instead, only the @Component decorator should be used with the class declaration directly following:

@Component({
  ...
})
export class ScoreListComponent { ... }

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 Google APIs sheet API is throwing an error message stating "Invalid grant: account not found"

I need to retrieve data from a spreadsheet using the Sheet API. After setting up a project in Google Cloud Platform and creating a service account, I granted the account permission to edit the spreadsheet. I then downloaded the credentials in JSON format. ...

Filtering arrays using JSONPath

I'm currently grappling with JSON paths and encountering a particular problem. Unfortunately, I am unable to display the exact original file I am dealing with, but I have replicated the issue using this simplified JSON: { "store": { "book" ...

Updating templates using Angular 2 observables for change detection

Looking to optimize performance, I am exploring the implementation of manual change detection on my components. The app structure is as follows: App -> Book(s) -> Page(s) In the AppComponent, I subscribe to an observable and then utilize the "markF ...

A tutorial on setting a component path as the main URL in Angular 6

I am working on an Angular 6 application that has multiple page routes. My goal is to set the home component as the root URL so that when the application initially serves (ng serve -o), instead of landing on localhost:4200, which is currently just a blank ...

Arranging a list of objects with a designated starting value to remain at the forefront

Consider the array and variable shown below: array = ['complete','in_progress','planned']; value = 'planned'; The goal is to always sort the array starting with the 'value' variable, resulting in: array ...

In TypeScript, it can be challenging to determine the equality between a value and an enum

I am encountering an issue with my simple code: enum Color { BLUE, RED } class Brush { color: Color constructor(values) { this.color = values.color } } let JSON_RESPONSE = `{"color": "BLUE"}` let brush = new Brush(JSON.parse(JSON ...

Removing Multiple Object Properties in React: A Step-by-Step Guide

Is there a way in React to remove multiple object properties with just one line of code? I am familiar with the delete command: delete obj.property, but I have multiple object properties that need to be deleted and it would be more convenient to do this i ...

Complex data in JSON format

Hello there, here is a snippet of JSON data: { "fields": [ "logoFileName", "logoFileName1", "companyEventIDUnique", "Date", "Event", "soldOut", "companyEventGroupDescription", "eventImage ...

Avoid including line breaks when using JSON_ENCODE to prevent any issues in the

When attempting to add a new record to my JSON file, I encounter an issue where after encoding the files, there are numerous instances of \ and \n. How can I go about removing these unwanted characters? JSON { "clients": [ { ...

How can I add a parameter to a JSON URL in Angular?

I'm looking to enhance my URL by adding a new parameter, but I'm unsure of the steps needed. ts.file route(name:string) { this.router.navigate(['/homepage', (name)]); console.log('name); } service private url1 = './assets/ ...

"Converting a JSON parameter file into a semicolon-separated string: a step-by-step

I have a JSON file containing parameters: [ { "ParameterKey": "code", "ParameterValue": "ab" }, { "ParameterKey": "env", "ParameterValue": "prod" }, { ...

When attempting to import the code, an error occurred with the message: "No matching resource found in the drawable folder"

After searching for code to display JSON parsed data in a list and store it in SQLite, I came across a tutorial on . However, upon opening the project, I encountered error messages as follows: - Information:Gradle tasks [:app:assembleDebug] ... (error mes ...

Utilize the <wbr> tag within FormattedMessage and assign it as a value while coding with TypeScript

Trying out the optional word break tag <wbr> in a message within <FormattedMessage id="some:message" />. Context Some words or texts are too lengthy for certain parent elements on smaller mobile screens, and we have a column layout t ...

The Angular application continues to display the outdated component HTML template in the browser even after it has been updated

In my role, I am currently focusing on developing Angular libraries that can be reused across various projects within our software department. One of these libraries includes a login form that I have successfully published to npm and integrated into anothe ...

Trigger a click event on a third-party webpage that is embedded within an Angular application

In the process of developing my angular application, I found a need to incorporate a graph visualization tool. To achieve this, I utilized the HTML <embed> tag and successfully integrated the graph into my application. Now, my objective is to enable ...

Tips for concealing a parent within a complexly nested react router structure

Is there a more efficient way to conceal or prevent the rendering of parent content within a react router object? I could use conditional rendering, but I'm unsure if that's the optimal solution. My setup involves a parent, child, and grandchild, ...

What is the convention for using one-letter function names in jQuery and JSON?

Could someone please clarify the functionality of this code snippet? One aspect that I find frustrating about this function is its use of a single-lettered name. How can I determine the purpose of this function and what triggers it to run? function ...

Tips For Implementing Pagination in Laravel 5.8 with Angular 8

Encountering issues when trying to retrieve the next set of results from the database using Laravel pagination. The results obtained are as follows from the route: api/getMerchants { "merchants": { "current_page": 1, "data": [], // con ...

Issue encountered while utilizing property dependent on ViewChildren

Recently, I designed a custom component which houses a form under <address></address>. Meanwhile, there is a parent component that contains an array of these components: @ViewChildren(AddressComponent) addressComponents: QueryList<AddressCo ...

Could you please share the standard naming convention used for interfaces and classes in TypeScript?

Here's what I have: interface IUser { email: string password: string } class User { email: string password: string constructor(email: string, password: string) { this.email = email this.password = password } isEmailValid(): boo ...