Я создаю приложение в React с использованием API Карт Google, и мне нужно реализовать обработку ошибок, если ключ API отсутствует или недействителен. Я почти уверен, что мне нужно использовать .then
и .catch
, но не уверен, где именно их разместить. Куда мне их положить? Я уже сделал это для другого API в том же приложении, я просто не уверен в этом. Вот мои Map.js и App.js.
Map.js:
/* global google */
import React, { Component } from 'react';
import { withScriptjs, withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps';
const MyMapComponent = withScriptjs(
withGoogleMap(props => (
<GoogleMap
defaultZoom={8}
zoom={props.zoom}
defaultCenter={{ lat: -36.186, lng: -87.066 }}
center={{
lat: parseFloat(props.center.lat),
lng: parseFloat(props.center.lng)
}}
>
{props.markers &&
props.markers.filter(marker => marker.isVisible).map((marker, idx, arr) => {
const venueInfo = props.venues.find(venue => venue.id === marker.id);
return (
<Marker
key={idx}
position={{ lat: marker.lat, lng: marker.lng }}
onClick={() => props.handleMarkerClick(marker)}
animation={arr.length === 1
? google.maps.Animation.BOUNCE
: google.maps.Animation.DROP}
>
{marker.isOpen &&
venueInfo.bestPhoto && (
<InfoWindow>
<React.Fragment>
<img src={`${venueInfo.bestPhoto.prefix}200x200${venueInfo.bestPhoto.suffix}`} alt={venueInfo.name} />
<p>{venueInfo.name}</p>
<p> {venueInfo.location['address']}</p>
{venueInfo.rating && <p> Rating: {venueInfo.rating}</p>}
{venueInfo.price && <p> Price: {venueInfo.price['message']}</p>}
<p> {venueInfo.description}</p>
<p> {venueInfo.url}</p>
{/* <p> {venueInfo.categories[]}</p> */}
</React.Fragment>
</InfoWindow>
)}
</Marker>
);
})}
</GoogleMap>
))
);
export default class Map extends Component {
render() {
return (
<MyMapComponent
{...this.props}
isMarkerShown
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div className="col" style={{ height: `100%`, width: `100%` }} />}
mapElement={<div style={{ height: `100%`}} />}
/>
);
}
}
и App.js:
import React, { Component } from "react";
import "./css/App.css";
import "./css/Fonts.css"
import SquareAPI from "./API/";
import Map from "./component/Map";
import SideBar from "./component/SideBar";
import Navbar from "./component/Navbar"
import Footer from "./component/Footer"
import * as googleMapsAPI from "./data/API_credentials";
const APIs = {
// Google Maps
googleMaps: {
// using the `params` attribute allows us to string multiple query
// parameters together later on without manual concatenation
params: new URLSearchParams({
// API stored in separate file
key: `${googleMapsAPI.key}`,
})
},
}
// Map component
class App extends Component {
constructor() {
super();
this.state = {
venues: [],
markers: [],
center: [],
zoom: 14,
googleMapURL: `${googleMapsAPI.url}${APIs.googleMaps.params}`,
updateSuperState: obj => {
this.setState(obj);
}
};
}
closeAllMarkers = () => {
const markers = this.state.markers.map(marker => {
marker.isOpen = false;
return marker;
});
this.setState({ markers: Object.assign(this.state.markers, markers) });
};
// Function for user marker click
handleMarkerClick = marker => {
this.closeAllMarkers();
marker.isOpen = true;
this.setState({ markers: Object.assign(this.state.markers, marker) });
const venue = this.state.venues.find(venue => venue.id === marker.id);
SquareAPI.getVenueDetails(marker.id).then(res => {
const newVenue = Object.assign(venue, res.response.venue);
this.setState({ venues: Object.assign(this.state.venues, newVenue) })
console.log(newVenue);
});
};
handleListItemClick = venue => {
const marker = this.state.markers.find(marker => marker.id === venue.id)
this.handleMarkerClick(marker)
}
handleError = (error) => {
this.setState({error})
console.log(error)
// const errorToString = error.toString()
// console.error(errorToString)
// Alert element
const newAlert = document.createElement("div");
newAlert.setAttribute("class", "alert alert-warning")
newAlert.setAttribute("role", "alert")
newAlert.innerHTML = "API error";
document.getElementById("navbar").appendChild(newAlert);
}
searchVenues = (query, limit) => {
SquareAPI.search({
near: "Nashville, TN",
query: query,
limit: limit
}).then(res => {
const { venues } = res.response;
const { center } = res.response.geocode.feature.geometry;
const markers = venues.map(venue => {
return {
lat: venue.location.lat,
lng: venue.location.lng,
isOpen: false,
isVisible: true,
id: venue.id
};
})
this.setState({ venues, center, markers });
// Error for foursquare API call failure
}).catch(error => {
// console.log(error)
// pass error message(s) to handelError()
this.handleError(error)
})
}
testFunction = (test) => {
console.log("test")
}
componentDidMount() {
this.searchVenues("juice+coffee", "10");
}
render() {
return (
<div className="App container-fluid">
<Navbar />
{/* <TopNav/> */}
<div className="row">
<SideBar {...this.state} handleListItemClick={this.handleListItemClick} />
<div className="col full-height">
<Map {...this.state}
handleMarkerClick={this.handleMarkerClick} />
</div>
</div>
<Footer />
</div>
);
}
}
export default App;