Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Fetching data, get object, but still have error. Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '0')

Cannot fix this error.
I receive data (object) from thingspeak.com via fetch method. Then I want to render three values from that object: name, temperature and time. I can see temperature and name but not time.
Here is my error in console:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘0’).
Any ideas?

import React, { useState, useEffect } from 'react'

const App = () => {

  const [channelInfo, setChannelInfo] = useState({});
  const [isLoading, setIsLoading] = useState(true);
  const [dateWithOffset, setDateWithOffset] = useState(null);

  const getThermoData = async () => {
    setIsLoading(true);
    const response = await fetch(`https://api.thingspeak.com/channels/618304/fields/1.json?results=1`);
    const data = await response.json();
    setChannelInfo(data);
    setIsLoading(false);
    timeConverter();
  }

  const timeConverter = () => {
    const channelDate = channelInfo.feeds[0].created_at;
    const date = new Date(channelDate);
    const timestampWithOffset = date.getTime();
    setDateWithOffset(new Date(timestampWithOffset));
  }

  useEffect(() => {
    getThermoData();
  }, [])

  return (
    <div className='card'>
      {
        isLoading ? <p className='loading'>Loading...</p> : <>
          <h5 className='channel-name no-select'>{channelInfo.channel.name}</h5>
          <p className='temperature-value no-select'>{channelInfo.feeds[0].field1}</p>
          <h5 className='channel-time no-select'>{dateWithOffset}</h5>
        </>
      }
    </div>
  )
}

export default App

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Calling timeConverter just after setting the new state with setChannelInfo(data); will throw you an exception due to 1) Initial channelInfo value is {} so there is no .feeds[0].created_at and 2) calling setChannelInfo will not update the variable immediately. It will be updated on next render only.

You can switch to useMemo, add undefined check, change initial state of channelInfo to undefined.

import { useState, useEffect, useMemo } from "react";

const App = () => {
  const [channelInfo, setChannelInfo] = useState();
  const [isLoading, setIsLoading] = useState(true);
  const dateWithOffset = useMemo(() => {
    if (!channelInfo) return "";

    const channelDate = channelInfo.feeds[0].created_at;
    const date = new Date(channelDate);
    const timestampWithOffset = date.getTime();
    return new Date(timestampWithOffset).toString();
  }, [channelInfo]);

  const getThermoData = async () => {
    setIsLoading(true);
    const response = await fetch(
      `https://api.thingspeak.com/channels/618304/fields/1.json?results=1`
    );
    const data = await response.json();
    setChannelInfo(data);
    setIsLoading(false);
  };

  useEffect(() => {
    getThermoData();
  }, []);

  return (
    <div className="card">
      {isLoading ? (
        <p className="loading">Loading...</p>
      ) : (
        <>
          <h5 className="channel-name no-select">{channelInfo.channel.name}</h5>
          <p className="temperature-value no-select">
            {channelInfo.feeds[0].field1}
          </p>
          <h5 className="channel-time no-select">{dateWithOffset}</h5>
        </>
      )}
    </div>
  );
};

export default App;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading