0

I am a new user of React.js. I have an array of objects that I am simply trying to log to the console. I can log the full "metrics" Array, but when I try to access a specific index; I get a message of "Cannot read properties of undefined (reading '1') "

I need to access this array, so that I may make use of the values on the UI. The console screen shot is attached...console.log() screenshot

Here is a sample of the data being read:

{isAvailable: true, state: 'API State: New API data received', timestamp: '2021-11-08 14:56:51.867426', metrics: Array(147), Symbol(topic): 'my-topic'} isAvailable: true metrics: Array(147) [0 … 99] 0: {name: 'ESM_DATA.ESM_INFOS[1].TICK_COUNT', value: '1472700451', type: 'DINT'} 1: {name: 'UT59_DO_RDOL', value: false, type: 'BOOL'} 2: {name: 'UT51_DO_BF', value: false, type: 'BOOL'} 3: {name: 'UT129_DNL', value: false, type: 'BOOL'}

The code I am using looks like this...

const PubSubFunctional = () => {
  
  const [arrayData, setArrayData] = useState([]);
  useEffect(() => {
    PubSub.subscribe('testingtopic').subscribe({
      next: (data) => {
    
        try {
     
          setArrayData(data.metrics);
          //console.log('value', data.value);
        } catch (error) {
          console.log('Error, Try again!');
        }
      },
      error: (error) => console.error(error),
      close: () => console.log('Done'),
    });
  }, []);

  console.log('1:', arrayData[1]);
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Peter M.
  • 1
  • 3
  • Please clarify, is the screenshot of the `arrayData`? – AGE Nov 08 '21 at 18:51
  • Please provide a sample of the data as text, not as a picture of text. You may want to take the [tour] and read [ask] as well so that you are prepared for later questions. The problem here is that you are attempting to log an element of an array that is not populated yet; `useEffect`, `next`, `setArrayData` all of these are asynchronous and occur at different times in the lifecycle. – Heretic Monkey Nov 08 '21 at 18:51
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Nov 08 '21 at 18:52
  • @HereticMonkey Here is a text sample of the json data : {isAvailable: true, state: 'API State: New API data received', timestamp: '2021-11-08 14:56:51.867426', metrics: Array(147), Symbol(topic): 'my-topic'} isAvailable: true metrics: Array(147) [0 … 99] 0: {name: 'ESM_DATA.ESM_INFOS[1].TICK_COUNT', value: '1472700451', type: 'DINT'} 1: {name: 'UT59_DO_RDOL', value: false, type: 'BOOL'} 2: {name: 'UT51_DO_BF', value: false, type: 'BOOL'} 3: {name: 'UT129_DNL', value: false, type: 'BOOL'} – Peter M. Nov 08 '21 at 19:30
  • @AGE Yes it is. I attached a a text sample of the raw data, in a comment below. – Peter M. Nov 08 '21 at 19:32
  • Did you happen to read the linked article? The problem is that data has not arrived when the `console.log` occurs. You need to structure your code such that it can handle the state where `arrayData` is empty and only eventually gets the data. By the way, in the future, it would be much easier if you use `console.log(JSON.stringify(obj, null, 2))` if possible, and [edit] your question to respond to comments asking for more information. – Heretic Monkey Nov 08 '21 at 19:39
  • @HereticMonkey Yes, Thank you. I read the article attached. It was somewhat helpful. – Peter M. Nov 08 '21 at 20:04

1 Answers1

0

The problem is that in useEffect you subscribe to some (probably remote) source, which will, after some time, send the data to your application, and then enqueue the new data via setArrayData. The setter of a hook effectively adds the new value to a component's queue and tells it "hey component, I need you to rerender soon with this new value for the hook". In the meantime, however, the remaining code of your application keeps executing. Which leads to a failure in trying to access element [1] of the array.

This is also a situation you will come across very frequently with REST calls and a useEffect & useState combo.

Often the best thing you can do in this case is to not render the component or provide a fallback while the data is not fully loaded. This has the additional advantage that your application will not go berserk if there's an outage on the specific endpoint you're interacting with.

manuelkruisz
  • 1,142
  • 7
  • 4
  • Yes. This seems to be the problem I am facing. Although I am unsure of the best way to approach it. – Peter M. Nov 09 '21 at 14:38