0

I'm using useEffect to make 2 requests to 2 different API's. I'm building an array based on the info that's getting returned. I'd like to access this array outside of useEffect and use it in the return below, where I want to use the data to render points on a map. When I try to access it, like how I'm using parkData it says all_data is not defined.

import React, {useEffect} from "react";
import {MapContainer, Marker, TileLayer } from "react-leaflet";
import * as parkData from "./data/skateboard-parks.json";
import "./App.css";
import axios from 'axios';

let all_info = []

export default function App() {

    const validator_url = "http://api-1.com"
    const ip_url = "http://ip-api.com/json/"
    
    useEffect(() => {
      async function fetchData() {
        const result1 = await axios.get(validator_url);

        for (let i = 0; i < result1.data.count; i+=1) {
          const result2 = await axios.get(`${ip_url}${result1.data.results[i].ip_address}`);

          let ip_address = result1.data.results[i].ip_address
          let lat = result2.data.lat
          let lon = result2.data.lon

          all_info.push([ip_address, lat, lon])
        }
      }
      fetchData();
    }, []);

  return (
    <MapContainer center={[45.4, -75.7]} zoom={12}>
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      {/* // HOW CAN I ACCESS all_info ARRAY HERE instead of using parkData? */}
      {parkData.features.map(park => (
        <Marker key={park.properties.PARK_ID} position={[park.geometry.coordinates[1], park.geometry.coordinates[0]]}>
        </Marker>
      ))}
    </MapContainer>
  );
}
1
  • 2
    Store it as state. Side note: You probably want to handle errors from that fetchData fucntion... Commented Dec 17, 2020 at 13:14

3 Answers 3

2

You will have to store that data in the internal state of the component instead of the global variable.

import React, {useEffect, useState} from "react";
import {MapContainer, Marker, TileLayer } from "react-leaflet";
import * as parkData from "./data/skateboard-parks.json";
import "./App.css";
import axios from 'axios';

export default function App() {
    const [allInfo, setAllInfo] = useState([]);
    const validator_url = "http://api-1.com"
    const ip_url = "http://ip-api.com/json/"
    
    useEffect(() => {
      async function fetchData() {
        const result1 = await axios.get(validator_url);
        const tempData = []

        for (let i = 0; i < result1.data.count; i+=1) {
          const result2 = await axios.get(`${ip_url}${result1.data.results[i].ip_address}`);

          let ip_address = result1.data.results[i].ip_address
          let lat = result2.data.lat
          let lon = result2.data.lon

          tempData.push([ip_address, lat, lon])
        }
        setAllInfo(tempData);
      }
      fetchData();
    }, []);

  return (
    <MapContainer center={[45.4, -75.7]} zoom={12}>
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      {/* // HOW CAN I ACCESS all_info ARRAY HERE instead of using parkData? */}
      {parkData.features.map(park => (
        <Marker key={park.properties.PARK_ID} position={[park.geometry.coordinates[1], park.geometry.coordinates[0]]}>
        </Marker>
      ))}
    </MapContainer>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

0

Try below:

{all_info?all_info.features.map(all_info => (
// your code
        
)):null}

1 Comment

Also use useState for storing the data ,like people have mentioned here
0

Create a state using useState hook to store the array and use that rather than defining the array outside the function.

export default function App() {
    const [allInfo, setAllInfo] = React.useState([]);
    
    const validator_url = "http://api-1.com"
    const ip_url = "http://ip-api.com/json/"
    
    useEffect(() => {
      async function fetchData() {
        const result1 = await axios.get(validator_url);
        const data = [];
    
        for (let i = 0; i < result1.data.count; i+=1) {
          const result2 = await axios.get(`${ip_url}${result1.data.results[i].ip_address}`);

          let ip_address = result1.data.results[i].ip_address
          let lat = result2.data.lat
          let lon = result2.data.lon

          data.push([ip_address, lat, lon]);
        }

        setAllData(prevState => [...prevState, data]);
      }
      fetchData();
    }, []);
    ...
    }

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.