CompiledIO
CompiledIO

Reputation: 158

API result not binding React-Redux component

Im busy writing a simple app from a tutorial and have run into a bit of a snag with my working API call. Now the API is definitely getting called as I can see the data being returned when debugging in the browser but the this.props.todos is always undefined. Now my suspicion is that its getting rendered before the async call finished but I can't seem to find exactly how to handle this situation to make my class wait before rendering.

Here is a link to my project on github. please feel free to use to code and build further. Todo Project

Here is my index.js

const store = configureStore();

store.dispatch(loadTodos());

render(
    <Provider store={store}>
        <App />
    </Provider>, 
    document.getElementById('root')
);
registerServiceWorker();

Here is the section of the actions that I call

export function loadTodosSuccess(todos) {
  return {
    type: types.LOAD_TODOS_SUCCESS, 
    todos
  };
}

export function loadTodos() {
  return function(dispatch) {
    return todoApi.getTodos().then(todos => {

      dispatch(loadTodosSuccess(todos));
    }).catch(error => {

      throw(error);
    });
  };
}

Here is my API call

static getTodos() {
      return fetch('http://5a0c1bfc6c25030012c335b5.mockapi.io/todos').then(response => {

        return response.json();
      }).catch(error => {

        return error;
      });
    }

And lastly here is my list component

import React, { Component, PropTypes } from 'react';
import Card from '../Card/Card'
import classes from './CardList.css';
import { bindActionCreators } from 'redux';
import * as todoActions from '../../Actions/TodoActions';
import {connect} from 'react-redux';

class CardList extends Component {
    constructor(props) {
        super(props);
      }
    render() {

        return (

            <div className={classes.cardList}>
            {
                this.props.todos.map((todo, index) => {
                    return <Card
                    click={() => this.deleteCard(index)}
                    key={todo.id}
                    title={todo.title}
                    summary={todo.summary}
                    dateToCompleteBy={todo.dateToCompleteBy} />
                })
            }
            </div>
        );
    }
}

function mapStateToProps(state, ownProps) {

    return {
        todos: state.todos
    };
}

function mapDispatchToProps(dispatch) {

    return {
        actions: bindActionCreators(todoActions, dispatch)
    };
}

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

Upvotes: 1

Views: 55

Answers (1)

Hemerson Carlin
Hemerson Carlin

Reputation: 7424

Your InitialState is an object which has todos:

{
  todos: [],
}

So on LOAD_TODOS_SUCCESS, you should updated it accordingly:

case types.LOAD_TODOS_SUCCESS:
  return {
    ...state,
    todos: action.todos
  }

Upvotes: 2

Related Questions