Encountered an issue while trying to read the property 'temp' of undefined within an HTML document

Can someone help me with this issue?

I'm facing an error with the JSON data retrieved from an API:

ERROR in src/app/weather/weather.component.ts(39,30): error TS2339: Property 'main' does not exist on type 'Iweather[]'

Here is the JSON data causing the problem:

{
  "main": {
    "temp": 28,
    "feels_like": 32.95,
    "temp_min": 28,
    "temp_max": 28,
    "pressure": 1008,
    "humidity": 78
  }    
}

I am struggling to display the JSON data in my HTML file.

Below is my interface definition:

    export interface IWeather {
        name : string;
        main: any[];
    }

This is a snippet of my services.ts file:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable, Subject } from 'rxjs';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/catch';
    import { Iweather } from './Data-Interface';


    @Injectable({
      providedIn: 'root'
    })
    export class WeatherServiceService {

      constructor( private http : HttpClient) { }

      getRequest(val) : Observable<Iweather[]>{
        let APP_ID ="myAPICode";
        let cityName = val;
        let url ='https://api.openweathermap.org/data/2.5/weather?q=' + cityName + '&units=metric&appid=' + APP_ID;
         return this.http.get<Iweather[]>(url);
      }
    }

This is part of my component code:

      import { Component, OnInit } from '@angular/core';
      import { WeatherServiceService } from '../weather-service.service';
      import { Iweather } from '../Data-Interface';
      import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
      @Component({
        selector: 'app-weather',
        templateUrl: './weather.component.html',
        styleUrls: ['./weather.component.css']
      })
      export class WeatherComponent implements OnInit {

        options: FormGroup;
        floatLabelControl = new FormControl('auto');
        constructor(private WeatherService : WeatherServiceService , fb: FormBuilder) { 
          this.options = fb.group({
            floatLabel: this.floatLabelControl
          });
        }

        public weatherData : Iweather[] = [];

        ngOnInit() {}

        public cityName ="";
        public Status = "true";
        public humidity = "";
        public pressure = "";
        public wind_speed = "";
        public weather = "";
        public temp :string;

        getWeatherReport(value) {
          this.Status = 'false';
          this.cityName =value;
          this.WeatherService.getRequest(this.cityName)
          .subscribe((data : Iweather[]) => {
            this.temp = data.main.temp;
            this.humidity = data.main.humidity;
            this.pressure = data.main.pressure;
            this.weatherData = data;
          }); 
        }
      }

And here is an excerpt from my HTML file:

       {{ weatherData.name }}

Answer №1

There are a couple of ways to address this issue:

1) Instead of using this.temp = data.main, try this.temp = data["main"] or

2) Another approach is to define an interface :

export interface Iweather {
    main: {
    temp: number,
    feels_like: number,
    temp_min: number,
    temp_max: number,
    pressure: number,
    humidity: number
        }
    };

Answer №2

The issue lies in the discrepancy between the interface property 'main' being defined as an array, while the API response treats it as an object rather than an array. One possible solution is to create a model object (let's call it MyData.model.ts) specifically for the 'main' object, and then update the interface to reflect this: main: MyData[]; If you are confident that only one main object will be returned from the API response, you can directly access it using index [0] in your code, otherwise you may need to iterate over it using a foreach loop.

Answer №3

Your data variable contains an array of the Iweather interface. In your subscribe method, you are attempting to access the main property directly from the array. Instead, you should iterate through its elements using a loop like foreach, or specify a specific index such as data[0] to access the main property.

.subscribe((data : Iweather[]) => {
        //since you need data for a single day, there is no need to loop
        this.temp = data[0].main.temp; 
        this.humidity = data[0].main.humidity;
        this.pressure = data[0].main.pressure;
        //You have declared weatherData as an IWeather[] array so I am not changing that.
        this.weatherData = data;
      }); 

Edit: I have revised the code block above. Since you are receiving and only require weather data for a single day, looping through the data is unnecessary. Simply retrieve the main property of the first element in the IWeather array.

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

TypeScript code runs smoothly on local environment, however encounters issues when deployed to production

<div> <div style="text-align:center"> <button class="btnClass">{{ submitButtonCaption }}</button> <button type="button" style="margin-left:15px;" class="cancelButton" (click)="clearSearch()"> {{ clearButtonCapt ...

Tips for receiving @ mentions in PrimeNg Editor using Quill and quill-mention with Angular

Currently, I have been given the task of adding a mentions feature to our text editors. The editor I am working with is the PrimeNg Editor, built on Quill. After some research, I came across the package quill-mention, which appears to be a potential soluti ...

Combining Angular and Material Design: matdrawer and mattoolbar creating an overlapping effect

I'm currently facing a challenge in trying to construct a drawer that includes a mattoolbar, intended to overlap the primary toolbar of my application. Despite my efforts, I have been unable to rearrange the drawer higher up in the component hierarch ...

An error was encountered at line 7800, character 18 in the three-core.d.ts file in the node_modules/@types/three directory. The error message reads: "Cannot find name 'VRDisplay

I encountered an error in my Angular 6 app while running ng serve ERROR in node_modules/@types/three/three-core.d.ts(7800,18): error TS2304: Cannot find name 'VRDisplay'. node_modules/@types/three/three-core.d.ts(7801,23): error TS2304: Canno ...

Error message in TypeScript with Puppeteer library: "Element not found"

Incorporating puppeteer-core as a dependency in my TypeScript project within Visual Studio 2019 has caused an issue during the build process. The error message displayed is shown by a red squiggly line under Element: https://i.stack.imgur.com/HfJCu.png ...

Exploring Angular's Implementation of D3 Force Simulation

Looking to incorporate a d3 force simulation in my Angular app. I have a run method that initializes and sets simulation options, as well as a ticked method that updates the simulation on each tick. However, I've encountered a few problems with this s ...

Ways to incorporate External JS and CSS files into Angular 5 (loading files with a delay)

I have encountered some challenges while attempting to import external JS and CSS files into my Angular 5 application. Below is the code snippet that I have tried so far: Component.ts : ngOnInit() { this.loadScript(); // also attempted with ...

"Troubleshooting: The Angular Check-All feature is unexpectedly selecting disabled checkboxes within the ngx data

Within ngx-datatable, I have implemented a functionality where some checkboxes are disabled based on certain conditions. However, when I try to select all checkboxes, even the disabled ones get selected. How can this issue be resolved so that disabled chec ...

Tips for seamlessly embedding Youtube iframes within Angular2 components. Resolving issues with unsafe value errors

ERROR: There seems to be an issue in the ./HomeComponent class HomeComponent - inline template:23:84. It is caused by using an unsafe value in a resource URL context. About my homeData model { id: 1, title: '2017 Super Bowl', graphic: 'ht ...

Discover the steps to initiate Firefox in Incognito Mode using NodeJS and Selenium!

Can anyone help me figure out how to launch Firefox in private mode using TypeScript? I have attempted the following code but it doesn't seem to work: static async LaunchFirefoxInPrivateMode():Promise<WebDriver> { //Setting up firefox capab ...

What could be causing the peculiar behavior I am experiencing when a child component attempts to display values from an object fetched in the parent component?

I am currently developing an Angular application and encountering a challenge when it comes to passing data from a parent component to a child component using the @Input decorator The parent component is named PatientDetailsComponent. Here is the TypeScri ...

Tips for securely encrypting passwords before adding them to a database:

While working with Nest.Js and TypeORM, I encountered an issue where I wanted to hash my password before saving it to the database. I initially attempted to use the @BeforeInsert() event decorator but ran into a roadblock. After some investigation, I disc ...

Errors encountered while starting Angular due to issues in package.json configuration

Summary: Encountered an error while using 'Angular' for the first time, indicating tsc was not found in the package.json file. Details: As a beginner with Angular, I followed an example from a book and attempted to start it with np ...

Combining the Partial<CssStyleDeclaration> union type with a dictionary can lead to potential typing complications when the implicit any flag is

Using VueJS v-bind:style binding makes it possible to set CSS variables. I am attempting to create a union type that allows for the object passed to v-bind:style to retain typings for CssStyleDeclaration, while also being relaxed enough to accept an arbitr ...

Angular4: Automatically disable button after it is clicked within ngFor loop

I am facing the issue of disabling a <button> in an ngFor loop after it has been clicked by the user. Each button corresponds to an element in the loop, so I need to distinguish them using separate boolean values. Below is a snippet of the HTML code ...

Is there a way to make a mat-form-field read-only?

Is there a way to make mat-form-field read-only in Angular for a view that allows users to read but not edit the content? ...

Retrieving latitude and longitude from place id in an Angular Google Maps component

Currently utilizing the google-maps component to extract latitude and longitude from Google Maps prediction data. Additionally, I have integrated a search bar using google-maps component. I have successfully implemented a search bar with ngx-google-places ...

Tips for sorting queries within a collection view in Mongoose:

I am working with Mongoose and creating a view on a collection. NewSchema.createCollection({ viewOn: originalModel.collection.collectionName, pipeline: [ { $project: keep.reduce((a, v) => ({ ...a, [v]: 1 }), {}), }, ], ...

Discover the combined type of values from a const enum in Typescript

Within my project, some forms are specified by the backend as a JSON object and then processed in a module of the application. The field type is determined by a specific attribute (fieldType) included for each field; all other options vary based on this ty ...

Angular: Determining when a form has returned to its original state

My current task involves working with a reactive form that comes with default values. I need to figure out how to prevent the user from saving changes until they have modified something, and then revert back to the initial state. Although I can subscribe ...