1

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);
3
  • who is listening to LOAD_TODOS_SUCCESS ? Commented Nov 24, 2017 at 11:20
  • Could you share your reducer as well? Commented Nov 24, 2017 at 11:25
  • I have added a link to the github project for you to see everything. Commented Nov 24, 2017 at 11:29

1 Answer 1

2

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
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.