Blog

Using Ionic2 with GeoLocation and WeatherAPI

Placeholder Avatar
Sameera Gayan
October 10, 2016

This blog post uses ionic 2.0.0-rc.o_

In my previous article, I gave a basic overview about ionic2 and its features. Now it is time to go beyond that and build something that actually works.

In this article, I’ll be building a simple weather app. Along with the standard functionality, it will also use the following features:

1 - Cordova plugins (GeoLocation in this case) in an ionic2 app. 2 - Obtaining data from an external JSON API.

Using Cordova plugins

As you may already know, hybrid apps are built using standard web technologies such as html5, css, and javascript. However, sometimes you may need to access the native (mobile) functionality of the device. For example, taking a photo by using the built-in camera on your mobile phone.

In such situations you will need to access the device hardware from your mobile app. This can be done by using cordova plugins. Using Cordova plugins directly is not easy, but luckily Ionic2 has a separate ecosystem called ionic native. Ionic native is a collection of cordova plugins wrapped around Angular2 to allow easy access the native components.

Currently they have a plugin for most common hardware usages and, as you will see shortly, it’s a quick and easy setup to add this to your project.

üìù - _If you are coming from ionic1 world, think of this as ngCordova for ionic2

Accessing external APIs

Just like accessing native functionality, your app at some point will need to read/write data from/to an external API. Most apps will have a backend API to handle data.

OK! Let’s get to work…

Weather App

As the name suggests, our weather app will read our current location and get the current weather from openweathermap API. To access their API, we need to have an access key. So first you need to register with them (free) and get your key.

Once you have registered, you will find your API key in the API keys tab.

screen shot 2016-09-27 at 2 59 09 pm

Now we have the API key, let’s start building our project!

Accessing the current location (via Geolocation plugin)

  • First we create an empty project. In your terminal run the following command:

    ionic start weatherApp blank --v2

    üìù I named my app weatherApp but you can call it any name you like. I am also using the blank template here

    üìù _If you dont have ionic2 installed, read this on installing ionic2

  • Now we have the project, let’s go into the projects folder:

    cd weatherApp

  • Next, install the geolocation plugin:

    ionic plugin add cordova-plugin-geolocation

  • Open home.ts and add this line underneath the existing import statements:

    import { Geolocation } from 'ionic-native';

  • Now we need to get our current position when the app loads. To do this we will call geolocation. In the constructor method add the following code:

    üìù First we’ll simply check if the plugin works by calling an alert on the coordinates.

constructor(public navCtrl: NavController) { Geolocation.getCurrentPosition().then((resp) => { alert("lat -" + resp.coords.latitude + "- long" + resp.coords.longitude) }) }

  • Let’s run the app and see if the location works.

    üìù - Since we are accessing native API, we cannot test this on the browser. So, to test this, you either need run it on the emulator or on a connected device. Here we will use the emulator:

    ionic emulate

  • When you run this for the first time, the Device / emulator will ask you for permission to read your current location. Click allow when requested.

screen shot 2016-09-23 at 2 30 38 pm

  • Then you should see your current location as latitude and longitude coordinates.

screen shot 2016-09-23 at 2 38 17 pm

Yay…that works! Now let’s create a way to pass this latitude and longitude to the weather API and read the results back.

You can read more about the openweathermap API here.

Accessing an external API

Although you can write the code to access an external API in home.ts, it is good practice to have it in a separate class. The ideal way to do this is via a provider. Let’s see how we can do this…

  • First create a provider class, which we will call Weather:

    ionic generate provider Weather

  • open the weather.ts class and add the following method:

``` import { Injectable } from ‘@angular/core’; import { Http } from ‘@angular/http’; import ‘rxjs/add/operator/map’;

@Injectable() export class Weather {

data: any;

constructor(private http: Http) {}

weatherForLocation(latitude, longitude){ return new Promise(resolve => { this.http.get(“http://api.openweathermap.org/data/2.5/weather?lat=” + latitude + “&lon=” + longitude + “&appid=").map(res => res.json()) .subscribe(data => { this.data = data; resolve(this.data); }) }) }

} ```

It looks like a lot of code, but let’s break it down. :)

weatherForLocation(latitude, longitude) is the method signature. It expects two parameters called latitude and longitude.

Then the results are wrapped around an Angular Promise. This is because HTTP requests are asynchronous requests and we need to wait until get we a result back from the API.

Ionic uses Angular HTTP to do HTTP requests. This is imported with the line:

import { Http } from '@angular/http';

Then it will map the JSON data to a parsed JS object.

Finally we resolve the promise and return the data.

üìù read this blog post from ionic to understand how this process works.

OK, now we are ready to pass the latitude and longitude we got from the Geolocation plugin to our provider.

‚ùó you need to add your provider to app.ts to be able to access it from the app.

  • open app.modules.ts
  • at the end of the existing import statements, add the Weather provider: import { Weather } from '../providers/weather';

  • in the providers array add the Weather provider: providers: [Weather]

Let’s go back to home.ts:

  • import Weather provider after the existing import statements: import { Weather } from '../../providers/weather';

  • after the class definition, define a variable to hold the weather data:

``` // importers export class HomePage {

   weatherData: any={};
   // more code   ```
  • create a separate method to call the Weather provider:

getWeather(latitude, longitude){ this.weather.weatherForLocation(latitude, longitude) .then(data => { this.weatherData = data; }) }

  • call the getWeather method from your GeoLocation plugin:

constructor(public navCtrl: NavController, public weather: Weather) { Geolocation.getCurrentPosition().then((resp) => { this.getWeather(resp.coords.latitude, resp.coords.longitude) }) } - now open home.html and update the html to show some additional details:

```

<ion-item *ngFor="let weather of weatherData.weather"> </ion-item>

```

Run your project again. You should now see your current city and its weather status. In my case it looks like:

screen shot 2016-09-27 at 4 03 09 pm

You can download the full source code here.

Happy hacking! :)