Using Google Places API
I am currently working on an App with a functionality that let’s a user search for a city (any city in the World), and be able to see photos from that said city. It took me a couple of days of research and numerous trial and error to come up with a working solution. I’m hoping that I can give you an idea of how to implement a functionality like this, in the next 5 min.
With all that said, let’s get started.
There’s a couple of reasons why I chose to start the implementation of this functionality by utilizing Google’s Place Autocomplete. Mainly, I wanted my user to be able to input any city in the world, while at the same time making sure that it is indeed a valid city. By predicting and giving our user options of cities that match what they are typing, we are also taking care of our input validations. Also, the information returned by the Place Autocomplete is vital for the implementation of the next step.
Implementing Place Autocomplete is fairly straight forward. In my app, I have a text input component. In the onChange (or onChangeText for Native) prop of our text input, we are going to pass a function that will make a GET request to the following URL:
The HTTP URL of Place Autocomplete has 2 required parameters: input and key. Input will be the value of our text input, and key is our API key. We can also pass some optional parameters in our request (more info about them in the docs). In our case, we are passing in a types parameter to specify what types of places we’ll get back in our response, which is (cities). (I don’t quite know why, but cities has to be in parenthesis if you pass it as a value of types. Other supported types do not have to be in parenthesis).
If you set up your GET request appropriately (I’m using fetch), you should receive a response that looks something like this:
This is a response to a call with an input of “Los”. The object is longer that the photo above. But simply put, it is an object that contains an array of city objects. Each city object will have different properties, but the two we are specifically interested in are the description and the place_id.
Now to let our user see these city predictions, we can create a list component that maps through the array of predictions and render each city object’s description. We’ll have to make each list element clickable, and have a click handler so we can retrieve the city object that our user is trying to search for. Once our user selects a city, we can use that city’s place_id for the next step.
Now that we have a city’s place_id, we can make a request to get more details about our selected city. This request can return a response containing more comprehensive information about a specified place, such as complete address, geometry, name, phone number, hours of operation (not relevant to our case), etc. Our request is going to be another GET request to the following URL:
This request requires 2 parameters: key (our API key) and place_id (from our user’s selected city). For our request, we are passing an optional parameter of fields with the value of photo. If our API request is set up properly, we should expect a response similar to this:
Passing fields=photo as a parameter to our API request will give us an array of photo objects. Unfortunately these photo objects do not contain photo URI’s. But what it does give us is a photo_reference that we can use for step 3.
The Place Photo service of the Places API is what gives us access to photos of a specified place. Besides our API key, a request to Place Photo requires a photo_reference parameter. This is the reason why we have to go through the other 2 services before we can have access to photos from our user’s city query. Our GET request will be to this HTTP URL:
The great thing about this request, is that it will respond back (if our request was set up properly) with an image URI. So what we can do, when we get the response from the Place Details request (from step 2), is map over the photos array (or in my case, pass it into a <FlatList/> component) and render an <Image/> component passing our request URL in the source prop like so:
Following these steps should render photos of any city that our user wants to query. Full disclosure, I haven’t gotten around to checking if it will work for every existing city in the world. But so far it hasn’t failed me yet. As an example, I used this functionality to search for a town/municipality in a remote island in the Philippines, called Capul. The first photo in this article (which I am bringing back, down below) are photos rendered from a query of that said town.
So whether our user inputs a famous city like Paris, or a small little town/municipality that no one has heard of before, as long as Google knows of that place, our implementation should work seamlessly!
(In case you were curious, I spent most of my early years in the small island of Capul. I remember when I was growing up, the town only had access to electricity from 6pm -11pm. And the only way to get to the island is by a 2 hr, once-a-day scheduled boat ride. It’s pretty remote in my opinion.)