1

When I put an array into the return everything works fine with the dispatch and rendering the items reducer-items.js. I am not sure what i missing but the data when i change is not showing

    export default function () {
          return [
              {id: 1, first: "Maxx", last: "Flinn", age: 17},
              {id: 2, first: "Allen", last: "Matt", age: 25},
          ]
    }

when I run an async function to retrieve the data from express server I am able to view the response and retrieve the data.

let items;
let callApi = async () => {
    console.log("calling API");

    const response = await fetch('/api/hello');
    console.log("response", response);

    const body = await response.json();

    if (response.status !== 200) throw Error(body.message);
    console.log("body API", body);
    items = body;
    return body;
  };


export default function () {
      return[ callApi() ]
}

server.js

const express = require('express');

const app = express();
const port = process.env.PORT || 5000;

var data = [
     {id: 1, first: "Maxx", last: "Flinn", age: 17},
     {id: 2, first: "Allen", last: "Matt", age: 25},
]


app.get('/api/hello', (req, res) => {

  res.json([
     {id: 1, first: "Maxx", last: "Flinn", age: 17},
     {id: 2, first: "Allen", last: "Matt", age: 25},
  ]);
});

app.listen(port, () => console.log(`Listening on port ${port}`));

I am not receiving any error but instead of rendering data[{},{}] i am rendering [Promise] and not seeing any data. Not sure if I am return correctly. my console.log on render shows.

 [Promise]0: 
    Promise__proto__: 
       Promise[[PromiseStatus]]: 
          "resolved"[[PromiseValue]]: 
                  Array(2)
   0:{id: 2, first: "Allen", last: "Matt", age: 25, }
   1: {id: 3, first: "Kris", last: "Chen", age: 23, …}

this is my item-list.js container

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import { selectedItem } from '../actions/index';

class ItemList extends Component {
  renderList() {
        return this.props.items.map((item) => {
            return (
                <li key={item.id}
                    onClick={() => this.props.selectedItem(item)}
                >
                    {item.first} {item.last}
                </li>
            );
        });
    }


   render() {
     console.log("render", this.props.items);
     return (
       <ul>

         {this.renderList()}
       </ul>
     );
   }
}
function mapStateToProps(state) {
  return {
    items: state.items,
  };

}

function matchDispatchToProps(dispatch) {
  return bindActionCreators({ selectedItem: selectedItem }, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(ItemList);

1 Answers1

0

Async functions returns promises, so you need to use it this way:

callApi().then((data) => {
    // use the data here...
});

If you call this function a lot of times you can push all promises into an array, then use Promise.all() to resolve all promises together. So you can take the Array [Promise] and do it:

Promise.all(arr).then((data) => {
    // in this case data will be an Array with the values
});
Gabriel Carneiro
  • 643
  • 5
  • 16
  • I tried export default function () { return callApi().then((data) => { return [data]; }); } . the same issue it is showing promise as pending. – David Pishchik May 14 '18 at 20:32
  • Now you're mixing up async and sync functions, you can't do it, take a look [here](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Gabriel Carneiro May 14 '18 at 20:35