Getting Started with Ionic: Angular Concepts & Syntax

Getting Started with Ionic: Angular Concepts & Syntax

Follow Josh Morony on

This article was originally written following the release of Ionic 2, and focused on the new concepts and syntax introduced in the new version of Angular, along with some comparisons to Ionic 1.x and AngularJS. Since then, Ionic 4 has been released which now allows us to use Ionic with any framework (not just Angular).

Angular still remains the most popular choice for Ionic development, so I decided to revisit this post and update it to be relevant today. This article focuses mostly on some basic concepts behind using Angular, which have mostly stayed the same since the initial release.


With the current iterations of the Angular and Ionic frameworks, we are able to make apps that perform better on mobile, adhere to the latest web standards, are scalable, reusable, modular, and so on.

As always, we continue to use the web tech (HTML, CSS, and Javascript) that we know and love to build applications, but there are some conceptual and syntax differences that we need to understand when using Ionic and Angular (versus standard HTML/CSS/JavaScript). For example, the HTML we use in our templates looks a little different than you might be used to:

<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

	<div class="ion-padding">
		The world is your oyster.
		<p>If you get lost, the <a target="_blank" rel="noopener" href="https://ionicframework.com/docs/">docs</a> will be your guide.</p>
	</div>

	<ion-list>
		<ion-item button *ngFor="let item of items" (click)="viewItem(item)">

		</ion-item>
	</ion-list>

</ion-content>

and the same goes for the Javascript:

import { Component } from '@angular/core';
import { NavController } from '@ionic/angular';

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

	constructor(private navCtrl: NavController){

	}

	viewItem(item){
		this.navCtrl.navigateForward('/items/' + item.id)
	}

}

If you’re already familiar with ECMAScript 6 or TypeScript then a lot of this will likely already look somewhat familiar.

I also have an introduction to ECMAScript 6 and Angular for Ionic developers, but in this post I wanted to dive into the actual syntax we will be using in Ionic/Angular applications.

Angular & Ionic Concepts

Before I get into the syntax, I wanted to cover a few new general concepts you might come across when learning Ionic & Angular.

Transpiling

Transpiling means converting from one language to another language. Why is this important to us? Basically, ES6 gives us all this new stuff to use, but ES6 is just a standard and it is not completely supported by browsers yet. We use a transpiler to convert our ES6 code into ES5 code (i.e. “normal Javascript”) that is compatible with the browsers of today. Once ES6 is widely supported, this step wouldn’t be necessary.

In the context of Ionic applications, here’s an idea of how it might look:

When we run ionic serve, our code inside of [the app folder] is transpiled into the correct Javascript version that the browser understands (currently, ES5). That means we can work at a higher level using TypeScript and ES6+, but compile down to the older form of Javascript the browser needs. - Ionic Website

You don’t need to worry about how this process works, this all happens automatically when you build your Ionic applications. However, it is useful to understand why you can use the fancy new JavaScript stuff.

Web Components

Web Components are kind of the big thing that is emerging now – they weren’t really feasible to use in Angular 1.x but the current version of Ionic is entirely based on web components. Web Components are not specific to Angular or Ionic, they are becoming a new standard on the web to create modular, self-contained, pieces of code that can easily be inserted into a web page (kind of like Widgets in WordPress).

In a nutshell, they allow us to bundle markup and styles into custom HTML elements. - Rob Dodson

Rob Dodson wrote a great post on Web Components where he explains how they work and the concepts behind it. He also provides a really great example, and I think it really drives the point home of why web components are useful.

Basically, if you wanted to add an image slider as a web component, the HTML for that might look like this:

<img-slider>
  <img src="images/sunset.jpg" alt="a dramatic sunset">
  <img src="images/arch.jpg" alt="a rock arch">
  <img src="images/grooves.jpg" alt="some neat grooves">
  <img src="images/rock.jpg" alt="an interesting rock">
</img-slider>

instead of this:

<div id="slider">
  <input checked="" type="radio" name="slider" id="slide1" selected="false">
  <input type="radio" name="slider" id="slide2" selected="false">
  <input type="radio" name="slider" id="slide3" selected="false">
  <input type="radio" name="slider" id="slide4" selected="false">
  <div id="slides">
    <div id="overflow">
      <div class="inner">
        <img src="images/rock.jpg">
        <img src="images/grooves.jpg">
        <img src="images/arch.jpg">
        <img src="images/sunset.jpg">
      </div>
    </div>
  </div>
  <label for="slide1"></label>
  <label for="slide2"></label>
  <label for="slide3"></label>
  <label for="slide4"></label>
</div>

Rather than downloading some jQuery plugin and then copying and pasting a bunch of HTML into your document, you could just import the web component and add something simple like the image slider code shown above to get it working.

Web Components are super interesting, so if you want to learn more about how they work (e.g. The Shadow Dom and Shadow Boundaries) then I highly recommend reading Rob Dodson’s post on Web Components. Since originally writing this article, I have also released articles of my own about various aspects of web components (and how they relate to Ionic):

However, keep in mind that some of these concepts are little on the advanced side. For the most part, you don’t actually need to know much about how web components work if you just want to use them in Ionic. If you are not interested in the mechanics of it all, then most of the time it is going to be as simple as dropping a web component into your template like this:

<ion-button>Click me</ion-button>

This is how Ionic works today, we can use the web components that Ionic provides to us, or we can create our own custom Angular components. By adding these tags to our templates, whatever functionality they provide will be embedded right there.

Ionic provides a lot of these pre-made components that we can just drop into our applications to create sleek mobile user interfaces, which is one of the reasons the Ionic framework is so powerful (Ionic does most of the work for us).

Classes

Classes are a concept from Object Oriented Programming. There’s quite a lot to cover on the topic of classes, and I’m not going to attempt to do that here. A good place to start understanding the concept of classes is Introduction to Object-Oriented JavaScript, but keep in mind this is the current (soon to be old) way of implementing objects in JavaScript. JavaScript has never had a class statement, so instead of creating actual classes functions were used to act as classes, but now we will be able to use an actual class syntax with ES6.

In general, a class represents an object. Each class has a constructor which is called when the class is created (this is where you would run some initialisation code and maybe set up some data that the class will hold), and methods that can be called (both from within the class itself, but also by code outside of the class that wants access to something).

We could have a Page object for example. That Page object could store values like title, author and date which could be initialised in the constructor. Then we could add some methods to the class like getAuthor which would return the author of the page, or setAuthor which would change the author.

How the concept of classes apply to Ionic/Angular applications should start to become apparent as you begin learning and building applications, but having a bit of background on the general concept helps.

Angular Syntax

Now let’s take a look at some actual Angular syntax that you will be using in your Ionic applications. Before I get into that though, I think it’s useful to know about the APIs that each and every DOM element (that is, a single node in your HTML like <input>) have.

Let’s imagine we’ve grabbed a single node by using something like getElementById(‘myInput’) in JavaScript. That node will have attributes, properties, methods and events.

An attribute is some data you supply to the element, like this:

<input id = "myInput" value = "Hey there">

This attribute is used to set an initial property on the element. Attributes can only ever be strings.

A property is much like an attribute, except that we can access it as an object and we can modify it after it has been created. For example:

var myInput = document.getElementById('myInput');
console.log(myInput.value); // Hey there
myInput.value = "What's up?";
console.log(myInput.value); // What's up?
myInput.value = new Object(); // We can also store objects instead of strings on it

A method is a function that we can call on the element, like this:

myInput.setValue('Hello');

An element can also fire events like focus, blur, click and so on – elements can also fire custom events.

Ok, now let’s take a look at some Angular code! There’s a great Angular cheat sheet you can check out here, I’ll be using some examples from there.

The examples in the following section are specific to Angular. The syntax we will be using and the functionality they achieve is something built-in to Angular, unlike the stuff up until this point which have mostly just been generic web concepts.

Binding a Property to a Value

<input [value]="firstName">

This will set the elements value property to the expression firstName. Note that firstName is an expression, not a string. This means that the value of the firstName variable (defined in your class) will be used here, not the literal string ‘firstName’.

Binding a Function to an Event

<ion-button (click)="someFunction($event)">

This will call the someFunction function and pass in the event whenever the button is clicked. You can replace click with any native or custom event you like.

Rendering Expressions with Interpolations

<p>Hi, {{name}}</p>

This will evaluate the expression and render the result in the template. In this case, it would just display the name variable here, but you can also create other expressions like {{1+1}} which would render 2 in the template.

Two Way Data Binding

Angular has a concept of two-way data binding, meaning that if we updated a value in our class the change would be reflected in the template, and if we changed the value in the template it would be reflected in the class.

We could achieve this two way data binding in Angular like this:

<input [value]="name" (input)="name = $event.target.value">

This sets the value to the expression name and when we detect the input event we update name to be the new value that was entered. To make this easier, we can use ngModel in Angular like this to achieve the same thing:

<input [(ngModel)]="name">

This syntax is just a shortcut for the same syntax we described above.

Creating a Template Variable to Access an Element

<p #myParagraph></p>

This creates a local variable that we can use to access the element, so if I wanted to add some content into this paragraph I could do the following:

<ion-button (click)="myParagraph.innerHTML = 'Once upon a time...'">

NOTE: This is just an example to show that you can access the properties of the paragraph tag using the template variable – you shouldn’t actually modify the content of elements using innerHTML in this way.

Structural Directives

<section *ngIf="showSection">

<li *ngFor="let item of items">

We can use structural directives to modify our templates. The *ngIf directive will remove a DOM element if the condition it is attached to is not met. The *ngFor directive can loop over an array, and repeat a DOM element for each element in that array.

Decorators

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

Decorators like @Component, @Directive and so on allow you to attach information to your components. The example above would sit on top of a class to indicate that it is a “component” and also additional information like the selector that should be used for the tag name, the path to the template that is being used with this class, and the associated styles as well.

You can read more about decorators here which is a preview from my book.

Import & Export

ES6 allows us to Import and Export components. Take the following component for example:

import { Component } from '@angular/core';
import { NavController } from '@ionic/angular';

@Component({
  selector: 'app-cool-component',
  templateUrl: 'cool-component.component.html',
  styleUrls: ['cool-component.component.scss'],
})
export class MyCoolComponent {

	constructor(private navCtrl: NavController){

	}

}

This component is making use of Component and NavController so it imports them. The MyCoolComponent component that is being created here is then exported.

Now you would be able to access MyCoolComponent by importing it elsewhere:

import { MyCoolComponent } from './components/my-cool-component/my-cool-component';

Depdendency Injection

Let’s take another look at one of the examples from above to briefly touch on what “dependency injection” is:

import { Component } from '@angular/core';
import { NavController } from '@ionic/angular';

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

	constructor(private navCtrl: NavController){

	}

	viewItem(item){
		this.navCtrl.navigateForward('/items/' + item.id)
	}

}

We first import the NavController at the top of the file. We then “inject” it through the constructor like this:

constructor(private navCtrl: NavController){}

By adding navCtrl as an argument in the constructor and assigning it a “type” of NavController (the thing we just imported) it will set up a reference to NavController for us on a class member called navCtrl. This means that we can then access the functionality that NavController provides using the navCtrl variable which is now accessible throughout the entire class. This is what we are doing inside of the viewItem method.

Summary

I hope that this article has been able to familiarise you with a few key concepts behind Ionic & Angular.

Of course, there is much more to learn about both Ionic & Angular on top of the concepts we have covered in this article (and even the stuff we have covered in this article have only been touched upon lightly). You will find plenty of additional tutorials on this website, as well as in my book, to help you along the way.

Check out my latest videos: