Jared Gilpin
Jared Gilpin

Reputation: 81

Why can't I reference object in an array in Redux?

I'm calling an array of objects from an API and loading them into state. I receive the payload back from the API and am able to load the entire array into my state. I am able to see the object in a console log, but when I attempt to access a specific value from a key, it only returns undefined.

  PullStocks: {
quote: [],
price: '',
news: [
  {
    datetime: '2018-05-11T09:10:00-04:00',
    headline: 'Your first trade for Friday, May 11',
    source: 'CNBC',
    url: 'https://api.iextrading.com/1.0/stock/aapl/article/7912789597255843',
    summary: 'No summary available.',
    related: 'AAPL,FB,OSTK,XRX'
  },
  {
    datetime: '2018-05-11T07:38:21-04:00',
    headline: 'FANG Stocks Have Ignited A Rally - Cramer\'s Mad Money (5/10/18)',
    source: 'SeekingAlpha',
    url: 'https://api.iextrading.com/1.0/stock/aapl/article/6776286739960540',
    summary: '         Stocks discussed on the in-depth session of Jim Cramer\'s Mad Money TV Program, Thursday  , May 10.    The market has been seeing negativity and selloff in the recent past. However, the non-believers have been converted to believers now. How did this happen? All it took was great earnings…',
    related: 'AAPL,AMZN,BIIB,BMRN,CELG,F,FB,FCX,GILD,GRPN,GRUB,INT31168144,KSU,NASDAQ01,NLY,NSC,ONL31168,REGN,Computing and Information Technology'
  }}

I can call state.Pullstocks.news[0] and it returns the full object in a console log. I have tried state.Pullstocks.news[0].datetime, which I assumed would work and it does not.

I am using Redux as my state management, but I can't reference the proper key even when the payload is being returned.

Here is the code for my component.

import React from "react";
import { push } from "react-router-redux";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import { getNews } from "../../modules/PullStocks";

const News = props => {
  const currentCompany = props.path.split("/");

  if (!props.news[0]) {
    props.getNews(currentCompany[2]);
  }
  return (
    <div className="widget">
      {console.log(props.news[0])}
      {/* <h1>{props.news[0]}</h1>
      {console.log(JSON.stringify(props.news))} */}
    </div>
  );
};

const mapStateToProps = state => ({
  news: state.PullStocks.news,
  path: state.routing.location.pathname
});

const mapDispatchToProps = dispatch =>
  bindActionCreators(
    {
      getNews
    },
    dispatch
  );

export default connect(mapStateToProps, mapDispatchToProps)(News);

What am I doing wrong?

Upvotes: 0

Views: 381

Answers (2)

Jared Gilpin
Jared Gilpin

Reputation: 81

Here is how it was solved. Added an else statement onto the original if statement in my component. I am then return placeholder data until the async call returns. Thanks devserkan.

  const News = props => {
  const currentCompany = props.path.split("/");

  if (!props.news[0]) {
    props.getIexData(currentCompany[2], "news");
    return <p>no data</p>;
  } else {
    return (
      <div className="widget">
        <h1>News</h1>
        {console.log(props.news[0].datetime)}
        {props.headline}
        {/* <h1>{props.news[0]}</h1>
        {console.log(JSON.stringify(props.news))} */}
      </div>
    );
  }
};

Upvotes: 1

devserkan
devserkan

Reputation: 17608

Edit: I might understood this wrong. You are already populating your state somewhere else if I don't see wrong. Then you are checking for the existence of the first item of news, if not doing a getNews action for specific thing. I wonder if there is not any first item, how does not console log fire an error?


If I am right you are seeing this problem since not returning anything in your if block:

if (!props.news[0]) {
    props.getNews(currentCompany[2]);
  }

Try like this:

if (!props.news[0]) {
    return props.getNews(currentCompany[2]);
  }

Since there is no return, code jumps to next return immediately and before getting your data tries to use it and fires the error.

Maybe it could be better use a class component and do this data fetching in componentDidMount.

Upvotes: 0

Related Questions