For those who are curious about using an alternative API to Google's Geocoding, check out LocationIQ: https://locationiq.com/. I found the documentation to be very simple if you follow the instructions. Here is a sample of my location.js code below:
//location.js
const axios = require("axios");
const HttpError = require("../models/http-error");
const API_KEY = "YOUR_API_KEY_HERE";
async function getCoordsForAddress(address) {
const response = await axios.get(
`https://us1.locationiq.com/v1/search.php?key=${API_KEY}&q=${encodeURIComponent(
address
)}&format=json`
);
const data = response.data[0];
console.log(data);
if (!data || data.status === "ZERO_RESULTS") {
const error = new HttpError(
"Could not find location for the specified address.",
422
);
throw error;
}
const coorLat = data.lat;
const coorLon = data.lon;
const coordinates = {
lat: coorLat,
lng: coorLon
};
return coordinates;
}
module.exports = getCoordsForAddress;
//places-controllers.js
const uuid = require("uuid/v4");
const { validationResult } = require("express-validator");
const HttpError = require("../models/http-error");
const getCoordsForAddress = require("../util/location");
const createPlace = async (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
console.log(errors);
// our error handling
//deyman bas tkun bi async bta3mul next..mesh throw li2an throw synchro
return next(
new HttpError("Invalid inputs passed, please check your data.", 422)
);
}
// const title = req.body.title;
const { title, description, address, creator } = req.body;
let coordinates;
try {
coordinates = await getCoordsForAddress(address);
} catch (error) {
return next(error);
}
const createdPlace = {
id: uuid(),
title,
description,
location: coordinates,
address,
creator,
};
DUMMY_PLACES.push(createdPlace); // unshift(createdPlace) if u want to add it as first element in the array
res.status(201).json({ place: createdPlace });
};
exports.createPlace = createPlace;
This code can be reused, just remember to change your API key when you create your free account. Also note that the response you receive is an array, so for now I will be just taking the first element.
others resource:
https://developers.arcgis.com/documentation/mapping-apis-and-services/tutorials/
or using Mapbox
I share here my code where I use MapBox instead of the Google API. You need to send a GET
request to/geocoding/v5/mapbox.places/{search_text}.json/?access_token={access_token}
See also https://docs.mapbox.com/api/search/
const getCoordsForAddress = async (address) => {
let data;
try {
const url = 'https://api.mapbox.com/geocoding/v5';
const endpoint = 'mapbox.places';
const searchText = encodeURIComponent(address);
const YOUR_MAPBOX_ACCESS_TOKEN;
const response = await axios({
method: 'GET',
url: `${url}/${endpoint}/${searchText}.json/?access_token=${YOUR_MAPBOX_ACCESS_TOKEN}`,
});
data = response.data;
} catch (e) {
throw new HttpError('Something went wrong', 500);
}
if (!data || data.status === 'ZERO_RESULTS') {
throw new HttpError(
'Could not find location for the specified address.',
422
);
}
const [lng, lat] = data.features[0].center;
return { lat, lng };
};