Home > Back-end >  Trying to render an API call inside of a mapped Array
Trying to render an API call inside of a mapped Array

Time:11-27

I'm making a stock web application.

I'm storing a fake user's "account" array by mapping over it and returning it into a table.

However, I want to use the "Symbol" inside the array to make a fetch call to an API.

And show how much the current stocks value is.

This helps the user compare how much the "TotalCost" is compared to the stocks current value.

Here's what I have so far

 const [account, setAccount] = useState([
        {
           "Symbol": 'AAPL',
            "Shares": 1,
           "TotalCost": 130,
        },
        {
            "Symbol": 'TSLA',
             "Shares": 1,
             "TotalCost": 1500,
         },
   
    ])


                            <table>
                                <tbody>
                                    {account.map((stocks)=> {
                                        const {Symbol , Shares, TotalCost} = stocks;
                                        return (
                                            <tr>
                                              <td>{Symbol}</td>
                                              <td>{Shares}</td>  
                                              <td>${TotalCost}</td>
                                              <td>
                                              {() => fetch("https://finnhub.io/api/v1/quote?symbol="   Symbol   "&token=12345678910" )
                                              .then(res=> res.json())
                                              .then(data =>{

                                           //how do I render data.c inside my table <td></td> tag 
                                                return JSON.stringify(data.c)
                                              })}
                                              </td> 
                                            </tr>
                                        )
                                    })}
                                </tbody>
                            </table>

CodePudding user response:

The 'React' way, and also the proper way to do what you are looking for is as follows:

  1. Initialize an empty result state.
  2. Return a blank table on the first render.
  3. Fetch the data inside of a useEffect() hook.
  4. Update the state when the query is finished.
  5. Render the data using the result state.

If you are not familiar with the useEffect hook (or hooks in general) take a look at the React docs for useEffect.

A component which does this would look like this:

import { useState, useEffect } from "react";

function Stocks() {
  const [account, setAccount] = useState([
    {
      Symbol: 'AAPL',
      Shares: 1,
      TotalCost: 130,
    },
    {
      Symbol: 'TSLA',
      Shares: 1,
      TotalCost: 1500,
    },
  ]);

  const [results, setResults] = useState([]);

  useEffect(() => {
    const fetchedResults = [];

    account.map(({Symbol, Shares, TotalCost}) => {
      fetch("https://finnhub.io/api/v1/quote?symbol="   Symbol   "&token=12345678910")
      .then((res) => res.json())
      .then((data) => fetchedResults.push({
        Symbol,
        Shares,
        TotalCost,
        Content: data.c
      }));
    });

    setResults(fetchedResults);
  }, [])

  return (
    <table>
      <tbody>
       {results.map(({Symbol, Shares, TotalCost, Content}) => (
         <tr>
           <td>{Symbol}</td>
           <td>{Shares}</td>  
           <td>${TotalCost}</td>
           <td>{Content}</td>
         </tr>
       ))                         
      </tbody>
    </table>
  )
}

Explanation:

  • useEffect(): When called with the dependency argument of [] (empty array), the callback inside the hook is called once and only after the component has rendered, which is when side effects such as HTTP requests should occur.
  • results: results is stored in state as we want the component to rerender when the results have been fetched, which is what state is for.
  • Related