In this Ionic tutorial, we will show you how to create mobile apps quickly using Ionic, Angular, and Capacitor. In other words, this tutorial is the starting point to learn Ionic Framework, Angular, and Capacitor. What you will get is not just creating and running Ionic-Angular apps, but a little bit more meaningful by displaying data in the Ionic list or grid, details, and Google maps. For more details about accessing data from REST API, Firebase, or Google Maps related, we have written the tutorials for you.
This tutorial is divided into several steps:
- Step #1. Preparation
- Step #2. Create an Ionic App with the Type of Angular
- Step #3. Modify Angular Routes
- Step #4. Display Data to the Ionic List/Grid
- Step #5. Display Data to the Ionic Card
- Step #6. Display Google Maps
- Step #7. Run and Test the Ionic/Angular Apps
The following tools, frameworks, and modules are required for this tutorial:
- Node.js (Choose the recommended version)
- Ionic with the type of Angular
- Capacitor
- Terminal or Node Command Line
- IDE or Text Editor (We are using Visual Studio Code)
Let's get started with the main steps!
Step #1. Preparation
The first step of this tutorial prepares the environment to create the Ionic Angular apps. We will use the Mac OS or the Windows environment (choose one of them) and download the Node.js https://nodejs.org/en/download. Install the downloaded Node.js to your Mac or Windows machine then check the version of Node.js by typing this command in the terminal or command line.
node -v
v18.16.0
npm -v
9.6.7
Next, we will install the Ionic CLI which now is version 7.1.1. Type this command in the terminal or command line to install it.
npm install -g @ionic/cli
Now, we have ready-to-use Ionic Frameworks, Angular, and Capacitor.
Step #2. Create an Ionic App with the Type of Angular
We will create an Ionic app with the type of Angular and default template using Tabs. To do that, type this command in the terminal or command line.
ionic start quickIonic tabs
Choose Angular as a type option then press Enter.
? Framework: (Use arrow keys)
> Angular | https://angular.io
React | https://reactjs.org
Vue | https://vuejs.org
Choose NgModules for Angular components because our apps are small apps. You can choose standalone components for larger mobile apps.
> NgModules
Standalone
Next, go to the newly created Ionic-Angular application then run the Ionic-Angular app for the first time.
cd .\quickIonic
ionic serve
To show the mobile size of your app, right-click inside the browser then choose inspect then choose the laptop/mobile icon on the top. So, the whole Ionic Angular app will be like this.
Step #3. Modify Angular Routes
Open the Ionic Angular app using IDE or text editor, we will use VSCode by typing this command after stopping the running Ionic-Angular app by pressing CTRL+C.
code .
We need to pass ID parameters to Tab2 and Tab3. So, we will modify the default or generate `src/app/tabs/tabs-routing.module.ts`. Just change the Angular routes constant to be like this.
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{
path: 'tab1',
loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule)
},
{
path: 'tab2',
loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule)
},
{
path: 'tab2/:id',
loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule)
},
{
path: 'tab3',
loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule)
},
{
path: 'tab3/:id',
loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule)
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/tabs/tab1',
pathMatch: 'full'
}
];
Step #4. Display Data to the Ionic List/Grid
To display data as Ionic List or Grid, first, we have to create an array of objects. We will put this array of objects in a separate file. For that, create a new Typescript file `src/app/player.ts` then add these lines of the export constant array.
export const Player = [
{ id: 1, name: 'Robbie Fowler', team: 'Liverpool', photo: 'assets/imgs/photo1.jpeg', lat: 53.430855, lng: -2.960833 },
{ id: 2, name: 'Paul Ince', team: 'Manchester United', photo: 'assets/imgs/photo2.jpeg', lat: 53.463097, lng: -2.291351 },
{ id: 3, name: 'Eric Cantona', team: 'Manchester United', photo: 'assets/imgs/photo3.jpeg', lat: 53.463097, lng: -2.291351 },
{ id: 4, name: 'Thierry Henry', team: 'Arsenal', photo: 'assets/imgs/photo4.jpeg', lat: 51.554902, lng: -0.108449 },
{ id: 5, name: 'Alan Shearer', team: 'Newcastle United', photo: 'assets/imgs/photo5.jpeg', lat: 54.975593, lng: -1.621678 },
{ id: 6, name: 'Dennis Bergkamp', team: 'Arsenal', photo: 'assets/imgs/photo6.jpeg', lat: 51.554902, lng: -0.108449 },
{ id: 7, name: 'Didier Drogba', team: 'Chelsea', photo: 'assets/imgs/photo7.jpeg', lat: 51.481683, lng: -0.190956 },
{ id: 8, name: 'Jurgen Klinsmann', team: 'Tottenham Hotspur', photo: 'assets/imgs/photo8.jpeg', lat: 51.604320, lng: -0.066395 },
{ id: 9, name: 'Robin Van Persie', team: 'Arsenal', photo: 'assets/imgs/photo9.jpeg', lat: 51.554902, lng: -0.108449 },
{ id: 10, name: 'David Beckham', team: 'Manchester United', photo: 'assets/imgs/photo10.jpeg', lat: 53.463097, lng: -2.291351 },
{ id: 11, name: 'Steven Gerrard', team: 'Liverpool', photo: 'assets/imgs/photo11.jpeg', lat: 53.430855, lng: -2.960833 },
{ id: 12, name: 'Ian Rush', team: 'Liverpool', photo: 'assets/imgs/photo12.jpeg', lat: 53.430855, lng: -2.960833 },
];
Next, open and edit `src/app/tab1/tab1.page.ts` then add these imports of Player array and Angular Router.
import { Router } from '@angular/router';
import { Player } from '../player';
Inject the Angular Router in the constructor params.
constructor(public router: Router) {}
Add the variables before the constructor to handle an array of objects and view type (list/grid).
persons = Player;
viewType = 'list';
Add these functions after the constructor to switch the view of the list or grid.
changeToGrid() {
this.viewType = 'grid';
}
changeToList() {
this.viewType = 'list';
}
Next, open and edit `src/app/tab1/tab1.page.html` then add these lines of HTML tags that display the list/grid from the array of objects.
<ion-header>
<ion-toolbar>
<ion-title>
Player
</ion-title>
<ion-buttons slot="end">
<ion-button *ngIf="viewType === 'grid'" (click)="changeToList()">
<ion-icon slot="icon-only" name="list-box"></ion-icon>
</ion-button>
<ion-button *ngIf="viewType === 'list'" (click)="changeToGrid()">
<ion-icon slot="icon-only" name="grid"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list *ngIf="viewType === 'list'">
<ion-list-header>
Premier League Legend
</ion-list-header>
<ion-item *ngFor="let p of persons" [routerLink]="['/tabs/tab2/', p.id]">
<ion-avatar slot="start">
<img src="{{p.photo}}">
</ion-avatar>
<ion-label>
<h2>{{p.name}}</h2>
<h3>{{p.team}}</h3>
</ion-label>
</ion-item>
</ion-list>
<ion-grid *ngIf="viewType === 'grid'">
<ion-row>
<ion-col *ngFor="let p of persons" size-lg="3" size-md="4" size-sm="6" size="12">
<ion-card>
<img src="{{p.photo}}" />
<ion-card-header>
<ion-card-subtitle>{{p.name}}</ion-card-subtitle>
<ion-card-title>{{p.team}}</ion-card-title>
</ion-card-header>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
As you can see, there are buttons in the toolbar that show and hide based on the list/grid types. The click action will trigger the change of list/grid view types. So, there are 2 types of <ion-list> or <ion-grid> that hide by the "viewType" variable.
Don't forget to change the Tabs name in `src/app/tabs/tabs.page.html` to make tabs and their content related.
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="tab1">
<ion-icon name="flash"></ion-icon>
<ion-label>Player</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab2">
<ion-icon name="apps"></ion-icon>
<ion-label>Details</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab3">
<ion-icon name="send"></ion-icon>
<ion-label>Maps</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
Step #5. Display Data to the Ionic Card
We make two options to display details in Ionic Card in Tab 2. First, we will display a default static Ionic Card content if there's no data coming from other tabs. Second, we will display the Ionic Card of details that come from the other tabs. To do that, open and edit `src/app/tab2/tab2.page.ts` then add or modify these imports of Angular OnInit, ActivatedRoute, Router, and Player array.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Player } from '../player';
Add implementation of Angular OnInit to the class name.
export class Tab2Page implements OnInit {
...
}
Inject the Angular ActivatedRoute and Router to the constructor.
constructor(public route: ActivatedRoute, public router: Router) {}
Add the variables before the constructor that holds the details object and Player array.
details: any;
persons = Player;
Add an Angular ngOnInit function that finds an object from the player array.
ngOnInit() {
if (this.route.snapshot.paramMap.get('id') !== 'null') {
const id = parseInt(this.route.snapshot.paramMap.get('id')!, 0);
this.details = this.persons.find(x => x.id === id);
}
}
We use ngOnInit because want to load the details from the array every tab 2 showed up. Next, add a function to navigate to Tab 3 or show Google Maps.
showMap(id: any) {
this.router.navigate(['/tabs/tab3/', id]);
}
Next, open and edit `src/app/tab2/tab2.page.html` then replace all HTML tags with these.
<ion-header>
<ion-toolbar>
<ion-title>
Details
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-card *ngIf="!details">
<img src="assets/imgs/anfield.jpg" />
<ion-card-header>
<ion-card-subtitle>Anfield Stadium</ion-card-subtitle>
<ion-card-title>Liverpool</ion-card-title>
</ion-card-header>
<ion-card-content>
Anfield is a football stadium in Anfield, Liverpool, Merseyside, England, which has a seating capacity of 54,074, making it the seventh largest football stadium in England. It has been the home of Liverpool FC since their formation in 1892. It was originally the home of Everton FC from 1884 to 1891, before they moved to Goodison Park after a dispute with the club president.
</ion-card-content>
</ion-card>
<ion-card *ngIf="details">
<img src="{{details.photo}}" />
<ion-card-header>
<ion-card-subtitle>{{details.name}}</ion-card-subtitle>
<ion-card-title>{{details.team}}</ion-card-title>
</ion-card-header>
<ion-card-content>
<ion-button (click)="showMap(details.id)">
<ion-icon slot="icon-only" name="map"></ion-icon>
</ion-button>
</ion-card-content>
</ion-card>
</ion-content>
As you see, there are two <ion-card> that display static details and details from objects based on details object's existence.
Step #6. Display Google Maps
In this step, we will show the Google Maps that come from the static latitude/longitude or dynamic latitude/longitude from the object. For that, open and edit `src/app/tab3/tab3.page.ts` then add or modify these imports of Ionic ViewChild, ElementRef, OnInit, Platform, ActivatedRoute, and Player object.
import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { Platform } from '@ionic/angular';
import { ActivatedRoute } from '@angular/router';
import { Player } from '../player';
Declare the Google Map and map variable before the @Component.
declare var google: { maps: { Map: new (arg0: any, arg1: { center: { lat: number; lng: number; } | { lat: null; lng: null; }; zoom: number; }) => any; }; };
let map: any;
Add the implementation of Angular OnInit in the class name line.
export class Tab3Page implements OnInit {
...
}
Inject the ActivatedRoute and Platform to the constructor.
constructor(public route: ActivatedRoute, public platform: Platform) {}
Add the variables of @ViewChild, details object, and Player array before the constructor.
@ViewChild('map', { static: false }) mapElement: ElementRef | undefined;
details: any = { id: null, name: '', team: '', photo: '', lat: null, lng: null };
persons = Player;
Add the Angular ngOnInit function that loads the Google Maps inside the Platform ready method.
ngOnInit() {
if (this.route.snapshot.paramMap.get('id') === null) {
this.platform.ready().then(() => {
map = new google.maps.Map(this.mapElement!.nativeElement, {
center: { lat: -6.930560, lng: 107.558439 },
zoom: 15
});
});
} else {
const id = parseInt(this.route.snapshot.paramMap.get('id')!, 0);
this.details = this.persons.find(x => x.id === id);
this.platform.ready().then(() => {
map = new google.maps.Map(this.mapElement!.nativeElement, {
center: { lat: this.details.lat, lng: this.details.lng },
zoom: 15
});
});
}
}
The Google Maps coordinate is based on data that come from the previous Tab, if the data is null then we put the static coordinate. Next, open and edit `src/app/tab3/tab3.page.html` then replace all HTML tags with these.
<ion-header>
<ion-toolbar>
<ion-title>
Show Google Maps
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div #map id="map"></div>
</ion-content>
As you see, there's just a <div> that holds Google Maps. To make this Google Maps work, we need to import or load the Google Maps Javascript API library to the `src/index.html` before the end of the <body> tag.
<body>
<app-root></app-root>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBgZZK8umUqJn8d5CoIZqWPJ_qtMfqD9q0"></script>
</body>
Google Maps only works if the <div> has a height. So, add these CSS codes to the `src/app/tab3/tab3.page.scss`.
#map {
height: 690px;
}
Step #7. Run and Test the Ionic/Angular Apps
In this step, we will be working with the Capacitor before running and testing the Ionic Angular apps for Android and iOS devices. First, remove and add all platforms from this Ionic app project by typing these commands.
ionic capacitor add android
ionic capacitor add ios
Now, you can run the Ionic Angular apps on Android and iOS devices. Type this command to run to the Android device and make sure the Android device is connected to your computer.
ionic capacitor build android
The Android studio will open this Ionic Angular project then you can choose your Android device or simulator then click the play button in the Android Studio toolbar.
ionic capacitor build ios
Same with Android, the XCode will open then you can connect your iPhone/iPad to your Mac. Choose your connected iOS device or simulator then click the play button to run the Ionic Angular app on the iOS device or simulator.
The app will look like this.
That it's, the Ionic Angular Tutorial: How to Create Mobile Apps Quickly. As usual, we always provide full working source codes from our GitHub.
We know that building beautifully designed Ionic apps from scratch can be frustrating and very time-consuming. Check Ionic 6 - Full Starter App and save development and design time. Android, iOS, and PWA, 100+ Screens and Components, the most complete and advance Ionic Template.
That just the basic. If you need more deep learning about Ionic, Angular, and Typescript, you can take the following cheap course:
- Ionic Framework (Advance) by Senchabox
- App Development with Ionic from Scratch
- Build a Beautiful CryptoCurrency App using Ionic
- Quick Mobile App Prototyping With Ionic Creator
- Ionic Apps with Firebase
- Hands-On App Development with Ionic
- Learn Mobile App Development with Ionic Framework
Thanks!