Home > Software design >  Async Function in ReactJS
Async Function in ReactJS

Time:02-23

I have a parent and child component and I was wondering how I would go about using an async function within the child component. I am currently using react hooks as well.

The code

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

// reactstrap components
import { Card, Container, Row } from "reactstrap";

// core components
import Header from "components/Headers/Header.js";
import LocationSearchInput from "../../components/Places";
import { useAuthenticator } from "@aws-amplify/ui-react";
import * as queries from "../../graphql/queries";
import { API, graphqlOperation } from "aws-amplify";
import { geocodeByAddress, getLatLng } from "react-places-autocomplete";
import * as _ from "lodash";
import mapStyles from "./mapStyles";

const MapWrapper = ({data, loc}) => {
  const mapRef = useRef(null);
  // const [location, setLocation] = useState();
  console.log("child props", data, loc);

  console.log("foo child", loc);
  let location = null;
  if(loc.length >0){

  }



const latLongAddress = async () => {
  try {
    geocodeByAddress(loc[0].HomeLocation)
    .then(results => getLatLng(results[0]))
    .then(latLng => {console.log('Success', latLng); location=latLng})
    .catch(error => console.error('Error', error))
 } catch (err) {
     console.log('error facing location:', err)
 }
}
  useEffect(() => {

    console.log("child mount");
    if(loc.length > 0){
        var x = latLongAddress();
        console.log("value of x", x);
    }

    let google = window.google;
    let map = mapRef.current;
    if(location)
    {
      console.log("latLong", location);
    }
    let lat = "40.748817";
    let lng = "-73.985428";
    const myLatlng = new google.maps.LatLng(lat, lng);
    const mapOptions = {
      zoom: 12,
      center: myLatlng,
      scrollwheel: false,
      zoomControl: true,
      styles: mapStyles,
    };

    map = new google.maps.Map(map, mapOptions);

    const marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      animation: google.maps.Animation.DROP,
      title: "Light Bootstrap Dashboard PRO React!",
    });

    const contentString =
      '<div ><h2>Light Bootstrap Dashboard PRO React</h2>'  
      "<p>A premium Admin for React-Bootstrap, Bootstrap, React, and React Hooks.</p></div>";

    const infowindow = new google.maps.InfoWindow({
      content: contentString,
    });

    google.maps.event.addListener(marker, "click", function () {
      infowindow.open(map, marker);
    });
  }, []);

  console.log("child render");
  return (
    <>
      <div
        style={{ height: `600px` }}
        className="map-canvas"
        id="map-canvas"
        ref={mapRef}
      ></div>
    </>
  );
};

const Maps = () => {
  const [foo, setFoo] = useState([]);

  const { user, signOut } = useAuthenticator((context) => [context.user]);

  const [pin, setPin] = useState([]);

  const fetchFoo = async () => {
    console.log(user.attributes.email);
    try {
      const todoData = API.graphql(
        graphqlOperation(queries.listEmployees, {
          filter: {
            Email: {
              eq: user.attributes.email,
            },
          },
        })
      ).then((response) => {
          console.log("fetch resp", response);
          setFoo(response.data.listEmployees.items);
        })
        .catch((err) => {
          console.log(err);
        });

    } catch (err) {
      console.log("error facing Todos:", err);
    }
  };
  console.log("parent render");

  useEffect(() => {
    console.log("parent mount")
    fetchFoo();
  }, []);

  var json = [{a: "a", b:"b"}]

  return (
    <>
      <Header />
      {/* Page content */}
      {/* {foo} */}
      <Container className="mt--7" fluid>
        <Row>
          <div className="col">
            {/* <LocationSearchInput /> */}
          </div>
        </Row>
        <Row>
          <div className="col">
            <Card className="shadow border-0">
              {/* <> */}
              <MapWrapper data={json} loc={foo}/>
              {/* </> */}
            </Card>
          </div>
        </Row>
      </Container>
    </>
  );
};

export default Maps;

CodePudding user response:

I assume you are trying to do API calls inside the async method. To do the async calls you have to wait for the data to return and use await.

For example: you can change your above code from:

      const todoData = API.graphql

to

      const todoData = await API.graphql

I hope you understand how to handle async/await. The problem is quite not clear on what you want on your question but I assumed this is what you meant by the problem.

CodePudding user response:

You only need a function with async keyword when you want to block code the code execution to next line with await keyword.

you function should be like this..

    const latLongAddress = async () => {
      try { let response = await geocodeByAddress(loc[0].HomeLocation);
setLocation(response.location)
     } catch (err) {
console.log(err)
setLocation(null)
     }
    }

Now to use it you first need to extract lcoation then you need to call google map api for this you need 2 useEffects. first one :

runs on compoenent load. useEffect(()=>{lanlongAdress()},[])

after you setstate in latlong adress you need other useEffect to proceed with google call based on location.

useEffect(() => {
if(location) {


   console.log("child mount");
    if(loc.length > 0){
        var x = latLongAddress();
        console.log("value of x", x);
    }

    let google = window.google;
    let map = mapRef.current;
    if(location)
    {
      console.log("latLong", location);
    }
    let lat = "40.748817";
    let lng = "-73.985428";
    const myLatlng = new google.maps.LatLng(lat, lng);
    const mapOptions = {
      zoom: 12,
      center: myLatlng,
      scrollwheel: false,
      zoomControl: true,
      styles: mapStyles,
    };

    map = new google.maps.Map(map, mapOptions);

}
 
),[location]}
  • Related