What is the best way to iterate over JSON data from an endpoint that contains multiple nested arrays using the .map() method?

Seeking to showcase weather API data from: ()

import Image from "next/image"

interface Hour {
    time_epoch: number
    time: string
    temp_c: number
    temp_f: number
    is_day: number
    wind_mph: number
    wind_kph: number
    wind_degree: number
    wind_dir: string
    pressure_mb: number
    pressure_in: number
    precip_mm: number
    precip_in: number
    humidity: number
    cloud: number
    feelslike_c: number
    feelslike_f: number
    windchill_c: number
    windchill_f: number
    heatindex_c: number
    heatindex_f: number
    dewpoint_c: number
    dewpoint_f: number
    will_it_rain: number
    chance_of_rain: number
    will_it_snow: number
    chance_of_snow: number
    vis_km: number
    vis_miles: number
    gust_mph: number
    gust_kph: number
}


async function getHourlyForecast() {
  const location = 'Pemberton'
  const apiKey = '84703323c7f94238a98203306233010'
  const response = await fetch(`http://api.weatherapi.com/v1/forecast.json?key=${apiKey}&q=${location}&days=1&aqi=no&alerts=no` , {
    cache: 'no-cache',})
  const data = await response.json()
  return data 
}

export default async function Forecast() {
  const forecast = await getHourlyForecast()
  console.log(forecast);

  return (
     <div>
        <h2 className="text-center">Hourly Weather Forecast</h2>
        <div className="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-7 gap-6">
        {forecast.forecastday.map((hour, index) => 
        (
          <div key={index} className="text-center rounded-lg flex flex-col items-center bg-green-950/25 p-10">
            <p>{new Date(hour.date).toLocaleString("en-US", { weekday: "short"})}</p>
            <img className="w-50 h-50"
              src={hour.hour.condition.icon}
              alt={hour.hour.condition.text}
              aria-label={hour.hour.condition.text}/>
            <div>
              <p className="bg-black/25 px-2 italic rounded-xl text-white mb-2">
                High:{" "}
                <span aria-label={`Maximum temperature: ${hour.hour.temp_c.toFixed()} degrees Celcius`}>
                  {hour.hour.maxtemp_c.toFixed()}°
                </span>
              </p>
              <p className="bg-black/25 px-2 italic rounded-xl text-white">
                Low:{" "}
                <span aria-label={`Minimum temperature: ${hour.hour.temp_c.toFixed()} degrees Celcius`}>
                  {hour.hour.temp_c.toFixed()}°
                </span>
              </p>
            </div>
          </div>
        ))}
        </div>
    </div>
   
  );
}

Successfully mapping data from Forecast.Current, yet encountering issues with mapping information from Forecast.Forecastday.Day object as it returns undefined. Would appreciate any assistance.

Tried: {forecast.forecastday.map((hour, index) => but received undefined.

Answer №1

Just make a few adjustments to your code.

export default async function WeatherForecast() {
  const forecast = await getDailyWeatherForecast();
  console.log(forecast);

  return (
    <div>
      <h2 className="text-center">Daily Weather Forecast</h2>
      <div className="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-7 gap-6">
        {forecast.forecast.daily.map((day, index) => (
          <div key={index} className="text-center rounded-lg flex flex-col items-center bg-green-950/25 p-10">
            <p>{new Date(day.date).toLocaleString("en-US", { weekday: "short" })}</p>
            <img
              className="w-50 h-50"
              src={day.condition.icon}
              alt={day.condition.text}
              aria-label={day.condition.text}
            />
            <div>
              <p className="bg-black/25 px-2 italic rounded-xl text-white mb-2">
                High:{" "}
                <span aria-label={`Maximum temperature: ${day.maxtemp_c.toFixed()} degrees Celsius`}>
                  {day.maxtemp_c.toFixed()}
                </span>
              </p>
              <p className="bg-black/25 px-2 italic rounded-xl text-white">
                Low:{" "}
                <span aria-label={`Minimum temperature: ${day.mintemp_c.toFixed()} degrees Celsius`}>
                  {day.mintemp_c.toFixed()}
                </span>
              </p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

A helpful tip - If this component is frequently re-rendering with the same data, consider using React Hook - useMemo to memoize the weather data and prevent unnecessary re-renders. Let me know if that solution works for you.

Answer №2

In order to iterate over the forecastday data and its nested properties, it is important to ensure that each level of nesting exists and is not undefined.

FOR EXAMPLE

const fetchForecastData = async () => {
  const forecastData = await getHourlyForecast();
  console.log(forecastData);

  return (
    <div>
      <h2 className="text-center">Hourly Weather Forecast</h2>
      <div className="grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-7 gap-6">
        {forecastData.forecastday.map((day, index) => (
          <div key={index} className="text-center rounded-lg flex flex-col items-center bg-green-950/25 p-10">
            <p>{new Date(day.date).toLocaleString("en-US", { weekday: "short" })}</p>
            {/* Ensure `day.hour` is an array and not undefined */}
            {day.hour && Array.isArray(day.hour) && day.hour.map((hour, hourIndex) => (
              <div key={hourIndex}>
                <img
                  className="w-50 h-50"
                  src={hour.condition.icon}
                  alt={hour.condition.text}
                  aria-label={hour.condition.text}
                />
                <div>
                  <p className="bg-black/25 px-2 italic rounded-xl text-white mb-2">
                    High:{" "}
                    <span aria-label={`Maximum temperature: ${hour.temp_c.toFixed()} degrees Celsius`}>
                      {hour.maxtemp_c.toFixed()}°
                    </span>
                  </p>
                  <p className="bg-black/25 px-2 italic rounded-xl text-white">
                    Low:{" "}
                    <span aria-label={`Minimum temperature: ${hour.temp_c.toFixed()} degrees Celsius`}>
                      {hour.temp_c.toFixed()}°
                    </span>
                  </p>
                </div>
              </div>
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

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

I'm experiencing difficulties in establishing a connection from Ionic to my remote database

I set up a database on Fauxten and now I'm trying to connect it to my project. Although I can open the link in my browser, nothing happens when I try to call it in the app. I can't figure out what I'm missing. import { Injectable } from &ap ...

Encountering a stubborn ERESOLVE error during the installation of React and React-DOM for a Next.js project

Setting up a new Next.js project on my Mac (M2) has proven to be quite challenging due to the persistent ERESOLVE error I keep encountering when trying to install react and react-dom. Despite attempting various troubleshooting steps, the issue remains unre ...

Is it acceptable to directly modify the state in React components when utilizing react-redux?

While browsing the internet, I came across various instances where individuals implemented click events by handling them through function calls within their components. These call functions would then directly modify the state using simple techniques like: ...

Changing the date format in DatePicker for Material-UI in a React application

I'm using Material-UI's datepicker, but the default format is "mm/dd/yyyy" and I need to change it to "dd/mm/yyyy", how can this be done? Here is the code for the component: <LocalizationProvider dateAdapter={AdapterDateFns}> <D ...

Code in Javascript to calculate the number of likes using Typescript/Angular

I have encountered a challenge with integrating some JavaScript code into my component.ts file in an Angular project. Below is the code snippet I am working on: ngOninit() { let areaNum = document.getElementsByClassName("some-area").length; // The pr ...

Nextjs 13.4: GET request with parameters results in a 404 error

Hey, I'm having some trouble trying to send a fetch request with the parameter id to my API. The id is a string and I am using a dynamic route folder [...id] in the Link element. The Link Element <Link href={`/books/${id}`}">Book Number {i ...

What is the process for submitting information to my Next.js API endpoint?

As part of my learning journey with Next.js, I am currently developing a test e-commerce website. To enhance the functionality, I am integrating a checkout system using Stripe. Initially, I was able to successfully implement the checkout feature with stati ...

What is the correct way to assign a value to the switch?

I have a switch for opening and closing that is being saved on Firestore. When the switch is closed, I want it to remain in the 'close' position, like this: https://i.stack.imgur.com/jjYe5.png Currently, the issue is that when I navigate to ano ...

The boundaries not matching up with the vertices in React Flow

Using Nextjs with a React Flow app If you're having trouble visualizing how your React Flow app works, take a look at this image: https://i.stack.imgur.com/lR7XG.png The problem I'm facing is that the edges (delivery lines) are not aligned with ...

Is there a way to switch out the navigation icons on the react-material-ui datepicker?

Can the navigation icons on the react-material-ui datepicker be customized? I've attempted various solutions without any success. <button class="MuiButtonBase-root MuiIconButton-root MuiPickersCalendarHeader-iconButton" tabindex="0&q ...

Unable to find the Popper component in Material UI

Material-UI version "@material-ui/core": "^3.7.0" I have a requirement to display Popper on hover over an element, but unfortunately, the Popper is not visible. This section serves as a container for the Popper component. import PropTypes from &apos ...

Exploring the use of a customizable decorator in Typescript for improved typing

Currently, I am in the process of creating TypeScript typings for a JavaScript library. One specific requirement is to define an optional callable decorator: @model class User {} @model() class User {} @model('User') class User {} I attempted ...

What is the best way to shorten text in React/CSS or Material UI based on the line height multiples?

I'm facing an issue with creating a Material UI card that contains text. My goal is to set a fixed height for the card and truncate the text if it exceeds 3 lines. Can anyone suggest the best approach to achieve this? Here's the code snippet I&a ...

Change attention between TextFields by pressing the Enter key

Is there a way to make pressing Enter on a MaterialUI TextField shift focus to the next field, similar to how the Tab key operates? <TextField label='Documento' name="document" autoComplete="document" autoFo ...

The image appears on the browser, however, it does not render within the <img> tag in

I am facing an issue with displaying images from a DigitalOcean space in my reactJS application. When I try to display the image using an img tag like this: const search = 'https://wantedoffice.dev.bucket.ams3.digitaloceanspaces.com/smartphone.png&a ...

Is tsconfig.json Utilized by Gatsby When Using Typescript?

Many blog posts and the example on Gatsby JS's website demonstrate the use of a tsconfig.json file alongside the gatsby-plugin-typescript for TypeScript support in Gatsby. However, it seems like the tsconfig.json file is not actually utilized for conf ...

What is the best way to create a random key using a factory function?

I am working on a function that generates objects, and I would like to be able to specify the key for the object as a parameter. However, when I try to do this, the function does not recognize the parameter properly and sets its name as the key instead. H ...

webpack compilation fails with error code 4294967295 while attempting to compile a react project

As I embark on my journey to create my very first React project following a tutorial, I encounter a roadblock. I am referencing the webpack configuration from a sample project, but upon running webpack, an error is thrown. Here's a glimpse into the np ...

How can an array of objects be sent as a query string to the endpoint URL in React?

I'm currently developing a react application and facing the challenge of dynamically constructing and appending query strings to URLs. This is necessary because I have a shared base endpoint for all links, but each link may require different parameter ...

Exploring the process of cycling through "Fetch" JSON data in React.js for a dynamic slider component after setting it to state

Still getting the hang of React, so please go easy on me! My main objective is to retrieve data from my personal JSON server and display it on a custom "Slider" component that I'm working on. Following a tutorial, I wanted to challenge myself by usi ...