Dan
Dan

Reputation: 2100

async await returning a Promise and not a value

Working on a fullstack app I am making a call to the backend that retrieves info from a DB and returns it. Thing is, when I expect to get the value, I only get a Promise {<pending>}. I have verified on the backend code that I actually get a response from the DB and send it back to the frontend so I am not sure why the promise is not being resolved. Any idea/suggestions on this?

Here is the component I am trying to call the backend on and display the information. The console.log is what displays the Promise {<pending>}

getTheAsset = async id => {
    try {
        const response = await this.props.getAsset(id)
            .then(result => {
                console.log("[DisplayAsset] Promise result: ", result);
            });

    } catch(error) {
        console.log("[DisplayAsset] error: ", error);
    }
}

render() {
    const asset = this.getTheAsset(this.props.match.params.id);
    console.log("[DisplayAsset] asset - ", asset);
    return (
        <div className="container">

        </div>
    );
}

The following is the redux action that makes the API call.

export const getAsset = (id) => async dispatch => {
  const response = await axios.get(`http://localhost:8181/api/asset/${id}`);
  dispatch({
    type: GET_ASSET,
    payload: response.data
  });
}

I have included a snapshot of the backend, showing that I am actually getting a value back from the DB. enter image description here

I have also found this great answer, but still did not have much luck applying it to my situation.

Upvotes: 0

Views: 188

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 84912

Async functions always return promises; that's what they do. Async/await exists to simplify the syntax relating to promises, but it doesn't change the fact that promises are involved.

For react components, you need to have a state value which starts off indicating that it hasn't been loaded, then you kick off your async work, and when it finishes you update the state. If necessary, you can render a placeholder while still loading.

state = {
  asset: null,
}

componentDidMount() {
  this.getTheAsset(this.props.match.params.id)
    .then(result => this.setState({ asset: result });
}

render() {
  if (this.state.asset === null) {
    return null; // or some other placeholder.
  } else {
    return (
      <div className="container">

      </div>
    );
  }
}

Upvotes: 5

Related Questions