0

I'm trying to parse a json received from external api.

My reducer is:

import { RECEIVED_FORECAST } from '../actions/index';
export default function ForecastReducer (state = [], action) {

switch (action.type) {
  case RECEIVED_FORECAST:
    return  Object.assign({}, state, {
      item: action.forecast
    })
  default:
    return state;
  }
}

Then main reducer goes like:

import { combineReducers } from 'redux';
import ForecastReducer from './forecast_reducer';

const rootReducer = combineReducers({
  forecast: ForecastReducer
});

export default rootReducer;

and container looks like

import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';

class WeatherResult extends Component {

render() {
  const forecast = this.props.forecast.item;
  {console.log('almost: ', forecast)}
  return (
    <div>
      <h1> </h1>
    </div>
  )
 }
}

function mapStateToProps({ forecast }) {
  return {
    forecast
  }
}

export default connect(mapStateToProps)(WeatherResult)

Output of the almost is exactly the same son as I supposed:

almost: 
  Object

    currently: {time: 1476406181, summary: "Drizzle", icon: "rain", nearestStormDistance: 0, precipIntensity: 0.0048, …}

    daily: {summary: "Light rain on Saturday and Thursday, with temperatures rising to 92°F on Wednesday.", icon: "rain", data: Array}

So, my question is, how can I show the value of, let's say forecast.currently.summary?

1) If I just try to insert it within {} I receive : 'TypeError: undefined is not an object (evaluating 'forecast.currently')'

2) I can't use mapping as the json might have other components added

Is there any method to get to this property directly, without mapping all the file?

Thanks

Olenka
  • 249
  • 3
  • 11
  • I did not get what you want to show ? Can you post code pices for `1` which you tried. Also you mentioned you want to `show`. By show you mean you want to render it in render method ? – Panther Oct 14 '16 at 03:41
  • You could try `const { forecast: { item: { currently: { summary } } } } = this.props` and then in render do `{ summary || 'no data available yet' }` or something. – steezeburger Oct 14 '16 at 03:44
  • @steezeburger thanks a lot for your idea! I tried it, and receive the same error. So up to evaluation of currently, it works. But when I try `const { forecast: { item: {currently} } } = this.props` I receive `TypeError: undefined is not an object (evaluating 'this.props.forecast.item.currently')`, so it looks like `item` is not being recognized as an object? Though in the console it looks like it is. So I guess, problem might be in the reducer.. – Olenka Oct 14 '16 at 07:11

1 Answers1

0

The problem you have is that you're requesting the data. That doesn't complete immediately. Think about what the app is doing while you're waiting for the weather data to arrive.

It's displaying something. In your case, the render method is failing because you're trying to show data that hasn't arrived yet.

The solution:

render() {
  const forecast = this.props.forecast;
  const text = forecast && forecast.item.currently.summary || 'loading...';
  return (
    <div>
      <h1>{text}</h1>
    </div>
  )
 }
}

This way you check if you already have the data and if not, you show something useful.

DDS
  • 4,035
  • 19
  • 32