Build a Places App with Foursquare and Google Maps using Onsen UI and AngularJS

Image for post
Image for post

In this tutorial we are going to learn how to use the Foursquare API and Google Static Maps API to create a Places App with Onsen UI and AngularJS. In this app we will be able to search for a particular place and filter the results by food, shops and outdoor places. There will be also an integrated static map which will lead to the Google Website once clicked.

Foursquare API gives us access to a huge database of different venues from all around the world. It includes a rich variety of information such as the place’s addresses, popularity, tips and photos. The access to the API is available for free and provides an easy setup.

Google Static API makes easy to visualize a location on a map using integrated markers. These tools, combined with the power of Monaca and OnsenUI, enable us to build a Place App in almost no time!

The app is structured into three views. The main view enables the user to search for places using a simple input box. This information is fetched from the Foursquare API and displayed in an ons-list, which contains some ons-list-item elements. Furthermore, there is an ons-button in the ons-toolbar which leads to a filtered view. In the filter view, the user has the possibility to filter the place’s categories (Food, Shops and Outdoor). In the main view, the user can also click on a cell which will be directed to a the details viewpage. In the details page, a static map containing the places location is generated using the Google Static Maps API. Some additional information, like the opening hours, will be displayed too. An insite version of the app can be seen below. The code is freely available to download on GitHub.

Getting the API keys

To get the API key from Foursquare, we first need to create an account on their website, click on “Create a new app” and fill in the details. At the new page, we will be granted with a Client ID and a Client Secret, both needed in order to be able to perform request to the API.

For getting the API key from Google, we have to visit Google Developers Console (with our Google account), create a new project and enable the access for the Google Static Map API. In the credentials section we can select a method to access to this API. In our case, we will restrict it to only from our GitHub gh-pages repository. For every request we will send to the Google Maps API, we need to attach the generated API key.

The Main View: JavaScript Part

We start by implementing the search function. First, we need to figure out what kind of request we have to do in order to get the data we desire. According to the documentation, we will do a simple HTTP request which will return JSON data. The URL is in the form:

The parameters are:

  • near: the place we want to look for. We will use the string in the textbox.
  • section: it will include the options for the filter (Shops, Cafe and Outdoors). Since we want this information to be persistent after the app has been closed, we will use LocalStorage to store the information.
  • client_id: the generated client ID from Foursquare.
  • client_secret: the generated secret from the Foursquare.
  • v: the version of the API that we are using.

In the search function, we will first change the variable state to isLoading and then read the filter options from the localStorage. Afterwards, the app will make an HTTP request using Angular $http core service. After the query will be executed, the variable state will be changed to noResults or loaded, depending on the returned output. If some data has been returned, it will be parsed from the returned JSON object.

Since we want to update the cells, once the user enters a different searchString, we need to keep track of the value of the variable searchString. We can do this by using Angular $watch function.

// in the main view controller ...
$scope.$watch('obj.searchString', function() {

The Main View: HTML + CSS

Each ons-list-item is responsible for representing a venue. The structure of the HTML consists mainly of a combination of ons-row and ons-col. For a better illustration, take a look at the image below.

Image for post
Image for post

Each list item consists of a single ons-row that contains itself three ons-col: the first column contains the photo of the place, the second displays important information about the place and the third column displays the chevron. The second column is splitted into four rows: the first one for the title, the second one for the rating, the reviews and the price, the third on for the address and the forth one for the category. Furthermore, we use ng-repeat to generate the right quantity of yellow and grey stars:

The style of the cells of the main view is pretty straightforward: most of the positioning is done by ons-row and ons-cell. The containing elements just need small adjustments. For more details, check out the GitHub Repo.

The more challenging part of the styling is the search box, which we want to stick to the view. Since iOS does not really support position: fixed, we need to use position: absolute and set the list-item-container height to 100%:

Furthermore, we need to style the chevron image since we created a custom image due to the bigger height of our cells.

Filter Page

For the JavasScript part, we will load the filter options into the scope of our controller. Furthermore, the values of the switches will be set according to the value of the options. We need to also watch the sliders in order to adjust the values of the filter options.

Once the user clicks on either the cancel or the apply button, the navigation controller will pop the page. If the apply button is clicked, the filter options need to be saved in the localStorage and the main view controller needs to reload the data and initiate a search. To communicate between the controllers, we use a custom event. The main view controller will listen to the event and the filter view controller will fire it once the apply button has been clicked.

Details Page

In order to get these information, we need to query the Foursquare API for details using a query like the following one:

According to the documentation, the parameters are as following:

  • venue_id: the ID of the place.
  • client_id: the generated client ID from Foursquare.
  • client_secret: the generated secret from Foursquare.
  • v: the version of the API that we are using.

The venue ID is retrieved from the search query executed in the mainview controller. When we push the page, the ID is given as a parameter and used inside the details controller.

After reading the ID, a query to the API will be executed. After the query has finished, our application will parse the desired data out of the returned JSON object.

We are almost done! In order to finish the application, we need to layout and display the page. For the static map we will use Google Maps Static API. The URL of the image will be like the following one:

<img ng-src="{{lat}},{{lng}}&key=AIzaSyBGmoYFxRHlmsK6LUPiPLWkeh0ti6iw2i4" />

The parameters are:

  • zoom: the zoom factor of the image.
  • size: the dimension of the image.
  • lat: the latitude of the location.
  • lng: the longitude of the location.
  • key: our google API key.

For more information, please consult the documentation. Ones the map has been clicked, the full version of the map will be displayed in Google Maps webpage (or mobile app):

For the HTML part we only need to put the data together. First we have an img of the map abd an ons-list that contains the address and the opening hours. We will also use a scope variable to show the loading spinner, as long as the data has not been completely loaded.

Finally we are done!

Both the Foursquare API and the Google Static Map API enables us to do much more than what we have seen in this tutorial. For those who are interested, take a look at the documentations:


The Web Tub

Pushing the web current through hybrid mobile and PWA…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store