0

Trying a simple code to map over an array and, for each result, search an API for that result and spit out data retrieved from the API.

import React from 'react';

const App = () => {

  let artistData = require('./mass-artists.json')

  artistData.map(
    (theArtist) => {
        fetch(`[url]https://api.scryfall.com/cards/search?q=a:[/url]"${theArtist}"`)
            .then((response) => {
              return response.json();
            })
            .then((myJson) => {
              console.log(JSON.stringify(myJson)); //returns the JSON data, so I know it's working
              console.log(myJson.data[0].name); //returns the first card name
            })
    }
  )

  return(<span>This is here so React doesn't yell at me about no return statement.</span>)
}

export default App;

The JSON file is just a list of names of Magic artists. The map maps over the list of artists and searches on the API for them. I want to do the usual thing I do with the map, i.e. display something on the front-end. But I'm having trouble getting anything to work. I can log things to the console or do any Javascript function such as setting something's innerHTML, but where/how would I put a return statement to show the result in, say, a span tag? Even such as "Hello!".

Thanks as always!

3
  • Learn about state. A re render with data fetched can be made with useState or setState. Commented May 25, 2019 at 23:59
  • I thought about setting the state (I've been learning about and using React hooks a lot) but how would that work for multiple things? I could see "setTheResult(myJson)" but it would get overwritten each loop in the map, right? Commented May 26, 2019 at 0:04
  • You could use Promise.all to batch requests, then deal with each request like that, or you could do it how you are and just set each response data in a unique part of the state so they don't overwrite, for example if you give them each a unique id. I recommend looking into redux to handle state, it's much easier, and for asynchronous actions redux-thunk or the more advanced redux-saga. Commented May 26, 2019 at 0:06

1 Answer 1

2

I recommend looking into either the new hooks api or old Class components in react if you need more help with state. The following code will search for the data and then set state so that the component will know to update. You also probably don't want to run that map directly in render because that will rerun your fetches each time the component updates.

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

const App = () => {
  const [artistsInfo, setArtistsInfo] = useState([]);

  useEffect(async () => {
    let artistData = require("./mass-artists.json");

    const promises = artistData.map(theArtist => {
      return fetch(
        `[url]https://api.scryfall.com/cards/search?q=a:[/url]"${theArtist}"`
      )
        .then(response => {
          return response.json();
        })
        .then(myJson => {
          return myJson.data;
        });
    });
    const results = await Promise.all(promises);
    // results is an array of arrays because that is what your data seemed to be
    // you could use lodash flatten if you want to get a single array

    setArtistsInfo(results);
  }, []); // empty array so it only runs once

  // you could have a second useState to add a loader if you want

  return artistsInfo.map(infoArray => {
    return infoArray.map(singleInfo => {
      return <span key={singleInfo.id}>{singleInfo.name}</span>;
    });
  });
};

export default App;
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.