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]}