Integrating Ionic 5 with ArcGIS JS API + [Simple Map Bonus]
Published: 2021-02-08 03:24:08

In this post, you will see how to integrate Ionic Framework 5 with ArcGIS JS API.

First of all, What's Ionic Framework? What's ArcGIS JS API?

Nowadays, mobile development isn't only with native code, as Swift/Objective C for IOS and Java/Kotlin for Android Platform. Many frameworks have a proposal for writing the same code for the two platforms. So you don't need to worry about replicating your mobile app code in different programming languages or frameworks. The most famous frameworks that do this type of development is React Native, Flutter, and the focus of this post, Ionic Framework.

Ionic Framework is a mobile hybrid development framework, free and open-source. It is web development based, making this easy for web developers and the newest versions support libs/frameworks like React, Vue, and Angular. So any front-end web developer was no problem working within. With an architecture based on MVC (model-view-controller), where the views are coded in HTML and controllers and models are written in typescript (a javascript superset). Getting out of the other frameworks or libs that is more look-a-likable a native development as Flutter and React Native. And now, this is your best friend... Until this post ends.

At last, ArcGIS is a Geographic Information System(GIS) framework. A GIS is an information system for gathering, managing, and analyzing geographic data. So you can analyze the spatial location and organize layers of information. Visualize data into maps and 3D scenes. Changing data into information that reveals patterns, relationships, helping users to make smarter decisions. The ArcGIS JS API is an ArcGIS API for javascript developers. Therefore, we can integrate all features of a GIS platform with javascript based apps.

Let's do it...

Requirements:
- Node.js

1 At first, install the latest Ionic Framework:

Run-on the command line:
```bash
$ npm install -g @ionic/cli
```
If there was an older version of the Ionic Framework on your computer. Run the commands below to upgrade to the latest version:

```bash
$ npm uninstall -g ionic
$ npm install -g @ionic/cli
```

2 Let's create an Ionic App:
 On Ionic Framework there are pre-made app templates, you've could choose blank (a blank template there is not more than a blank page), tabs(a tabbed template app),  side menu (an app with a side menu pre-configured), and more. You can see more running the command <code>ionic start --list </code>. 
For our project, run the command:

```bash
$ ionic start myMap blank
```

We've just needed a simple blank page for our app. So let's take a blank app.

When we run the command above appears on the terminal a question to choose the framework. On the list option there are Angular, React, and Vue.js, we are going to choose Angular. Another question is if you want to use Capacitor, which is a cross-platform runtime-created by the Ionic team that allows it to add native platform features to the new app, as access to the camera, geolocation, etc. 

The older Ionic Framework versions used to use Cordova from the commercial Adobe PhoneGap project, but Capacitor has more approach to Web Progressive Apps.

3 After waiting a few minutes on the npm dependencies install process. Run our newest Ionic app:

Enter in the created folder called myMap and run the commands below:
```bash
cd myMap && ionic serve
```
This command above will run our app and open a new tab on your browser. Where we can see changes on the screen and the logs in the browser console.  If you want to see the log to debug our app open the browser's inspector.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bf67gju4n4kzk8zzs8en.png)


4 Now, Let's integrate our app with ArcGIS JS API:

Inside our new app folder, run the command below to add ArcGIS to our project dependencies:

```bash
npm install @arcgis/core --save
```

Before we start coding, let me explain how an Ionic application is structured.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/52f2b29vtxr7k65yotjs.png)

It is composed of three folders and configuration files. The first folder, e2e, is a test configuration folder. Below is a folder called node_modules where all the npm dependencies our project will need are located. And main folder, and the most important for us, src.

In the folder src, there are typescript configuration files, the main HTML page called index.html, a global sass file, and four folders (app, assets, environments, theme).

<ol>
 <li><strong>app:</strong> views, controllers and models. The main folder project</li>
<li><strong>assets:</strong> images, icons, and other media files used in the project</li>
<li><strong>environments:</strong> environments config file</li>
<li><strong>theme:</strong> there is a sass theme file, the global theme of the project.
</ol>

5 Let's put our hands-on coding

At first, add ArcGIS assets config to angular.json. On assets array in angular.json add a new element with the config assets from ArcGIS JS API.

```javascript
# angular.json
{
  "assets": [
    //The new element added to assets array.
    {
      "glob": "**/*",
      "input": "node_modules/@arcgis/core/assets",
      "output": "/assets/"
    }
  ]
}
```
In the same folder, open the file index.html, and in the head, tag put the code below. 

```html
<link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.18/"></script>
```

Now we gonna put a map on our blank page. In the folder app, open the folder home. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/c5pd9rlqcbgjhuxh8ibw.png)

In the file home.page.js, the class home had to implement the interface OnInit( an angular interface to execute code after initialize Angular) and its method ngOnInit.

```javascript
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {

  constructor() {}
  ngOnInit(): void {
    throw new Error("Method not implemented.");
  }
}
```
Import to HomePage MapView and Map from @arcgis/core:

```javascript
import Map from '@arcgis/core/Map';
import MapView from '@arcgis/core/views/MapView';
```
In the method ngOnInit replace the fragment <code>throw new Error("Method not implemented.");</code> to:

```javascript
 const map = new Map({
      basemap: "topo-vector" //Reference to the base of the map
    });

    const view = new MapView({
      container: "container", // Reference to the view div created 
      map: map, // Reference to the map object created before the view
      zoom: 4, // Sets zoom level based on level of detail (LOD)
      center: [15, 65] // Sets center point of view using longitude,latitude
    });
    
  }
```
And this is how our HomePage class would be:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d7l4jvdtytceq6xnn3os.png)

6 Let's show our map...

In the same folder open the file home.page.html to make some changes. Let's change the title and the div with id called container.

From this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kehya8j0p3smrkqvw9nv.png)

To this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cnrjzdrd2uifzzcwkl75.png)

And now we are going to change the dimensions of our div. Open the file home.page.scss and change the #container selector to this:

```css
#container {
  text-align: center;
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  right: 0;
}
```
So... Voilà!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w15l95kn0gz0p9zkb5ju.png)

This is our baby map. But this is not the end. 

Do you remember the Capacitor mention at the beginning of this post? Yes, we going to use it to get our location.

In the file home.page.ts add the import bellow:

```javascript
import { Geolocation} from '@capacitor/core';
```
And variables:

```javascript
latitude: number;
longitude: number;
```
Let's change the ngOnInit method to receive an async transaction: 

From this:
```javascript
ngOnInit(): void {
}
```
To this:
```javascript
  public async ngOnInit() {
  }
```

In the modified ngOnInit method add the fragment code below:

```javascript
...
 const position = await Geolocation.getCurrentPosition();
 this.latitude = position.coords.latitude;
 this.longitude = position.coords.longitude;
...
```
The fragment above is getting the coordinates from your location and save them in the variables longitude and latitude.

Add the coordinates to the center property of the MapView declaration.

```javascript
 const view = new MapView({
      container: "container", // Reference to the view div 
      map: map, // Reference to the map object created before the view
      zoom: 4, // Sets zoom level based on level of detail (LOD)
      center: [this.longitude, this.latitude] // Sets center point of view using longitude,latitude
    });
``` 
And how it is going... The result of our simple project.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9992pmd0yeb9enqueug6.png)

If you are lost or just wanna play with it. Right here is the Github repo from this tutorial.
{% github deecarneiro/SimpleMap-IonicArcGIS no-readme %}