Home > Software engineering >  React mapping multiple arrays from two different apis
React mapping multiple arrays from two different apis

Time:10-30

[![enter image description here][1]][1]how can i map multiple arrays to display the information on table style fetched from this two api's? right now my code displays the information but in two separate tables. i want it to display it in one table.

[1] How is displaying right now -- > https://i.stack.imgur.com/9D14i.jpg , [2] How it should display -- > https://i.stack.imgur.com/DoauM.jpg , [3] API information -- > https://i.stack.imgur.com/VVvgG.jpg , https://i.stack.imgur.com/ETb99.jpg

MY CODE

import axios from "axios";
import React, { useState, useEffect } from "react";

const Ranking = () => {
  const [playerName, setPlayerName] = useState([]);
  const [playerRank, setPlayerRank] = useState([]);

  const fetchData = () => {
    const playerAPI = 'http://localhost:3008/api/players';
    const playerRank = 'http://localhost:3008/api/highscore/players';

    const getINFOPlayer = axios.get(playerAPI)
    const getPlayerRank = axios.get(playerRank)
    axios.all([getINFOPlayer, getPlayerRank]).then(
      axios.spread((...allData) => {
        const allDataPlayer = allData[0].data.players
        const getINFOPlayerRank = allData[1].data.players

        setPlayerName(allDataPlayer)
        setPlayerRank(getINFOPlayerRank)
      })
    )
  }
  
  useEffect(() => {
    fetchData()
  }, [])

  return (
    <table >
      <tr>
        <th>Rank</th>
        <th>Name</th>
        <th>Points</th>
      </tr>
        <tbody>
          {playerRank && playerName?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.name}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}
        </tbody>
        {playerRank?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.id}</td>
                <td>{player.position}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}

    </table>

  )
        }

export default Ranking

THIS DOES NOT WORKS

          {playerRank && playerName?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.name}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}

THIS WORKS but it displays two tables because of this code how can i fetch both information inside one table?

  return (
    <table >
      <tr>
        <th>Rank</th>
        <th>Name</th>
        <th>Points</th>
      </tr>
        <tbody>
          {playerName?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.name}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}
        </tbody>
        {playerRank?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.id}</td>
                <td>{player.position}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}

    </table>

  )
        }

CodePudding user response:

Considering id being common property of objects in both the arrays. You can map it like this.

const nameAPI = [
  { id: 1, name: "John", status: "a" },
  { id: 2, name: "Alice", status: "b" },
];
const rankAPI = [
  { id: 1, score: 100, position: 1 },
  { id: 2, score: 80, position: 2 },
];

const table = nameAPI.map((nameObj, i) => {
  let temp = rankAPI.find((rankObj) => rankObj.id === nameObj.id);
  return { ...nameObj, ...temp };
});

After this you can map over the table object like your would normally do.

NOTE: This becomes a performance issue on UI side. I would suggest to do this same operation on backend side and then just map the output.

CodePudding user response:

axios.spread((...allData) => {
        const allDataPlayer = allData[0].data.players
        const getINFOPlayerRank = allData[1].data.players

        setPlayerName(allDataPlayer)
        setPlayerRank(getINFOPlayerRank)
        const twoArrayes = [...allDataPlayer,...getINFOPlayerRank]
        setPlayerName(twoArrayes)

      })
 <tbody>
          {playerName?.map((player) => {
            return (
              <tr key={player.name}>
                <td>{player.name}</td>
                <td>{player.score}</td>
              </tr>
            )
          })}
        </tbody>
  • Related