The Ionic Framework enables the creation of cross platform mobile applications with HTML, CSS and JavaScript(Angular). Ionic 1 was built with Angular 1.*, and with Angular 2 recently released, the second major version of Ionic is also imminent.

You already know HTML/CSS/JS

You can leverage the skills you already have from developing web applications with HTML, JavaScript and CSS to build cross-platform mobile apps. If you work with Angular 2, this will be a seamless transitions.

In fact, in the last Angular Connect conference, some members of the Ionic team spoke about ionic and progressive web apps.

Examples of progressive web apps made with ionic 2 can be found in pwa.ionic.io. Just visit any of the apps in your chrome browser on your phone, click on menu and tap Add to Home Screen. You'll then be able to load it as an app from your home screen.

Target all major mobile platforms

If you need to quickly build an app for all major mobile platforms (Android, iOS and Windows Phone), having one codebase may be the fastest way to do it, and Ionic is perfect for such a scenario. Updating the app, or rolling uout updates is just as easy as editing one code base.

We will build a simple app that consumes the github api. Our app will list github users, offer a search box for searching users, and be able to view the number of followers, repos, and gists the user has.

Ionic 2 is built on top of Cordova, a framework that enables development for cross patform apps with HTML, CSS and JavaScript. Make sure you have nodejs installed.

Install Cordova

Free Node eBook

Build your first Node apps and learn server-side JavaScript.

📧

Nice!

Check your email to confirm your subscription.

$ npminstall -g cordova

For Mac/Linux/Unix users, if you see errors with EACCESS, you can run the command as root user with sudo npm install -g cordova, or just fix your npm persmissions..

Install Ionic CLI

$ npminstall -g ionic

Note: If you see errors you don't understand, you may want to uninstall previous versions of ionic-cli with npm uninstall -g ionic, clear your cache with npm cache clean and then now install ionic-cli with npm install -g ionic

This installs the Ionic CLI into your workstation, and now we are good to go.

NOTE To check the details of your installed ionic, simply run

$ ionic info

You should see results almost similar to this

You can ignore the warnings for now. Most of them are only necessary when we want to deploy or build to either ios or android.

Finally, we need to have TypeScript. TypeScript is a superset of JavaScript, and works really well with Angular 2, you can go through the articles by this author to quickly get up to speed with TypeScript.

Ionic 2 provides a simple starter template to quickly scaffold a simple app. Our app will be called githubIonic, and so we'll quickly scaffold it with the ionic cli.

In your terminal:

$ ionic start githubIonic tutorial --v2

The above command scaffolds an ionic project based on a tutorial template ionic provides. It then downloads the necessary npm packages. We'll build the application using TypeScript, and that's why we have a --ts flag.

Go to the githubIonic directory with cd githubIonic. We'll serve the app first, then go through the folder structure. In your terminal, run:

$ ionic serve

You may be asked to select how you would like to serve the ionic app, select localhost:8100 option. Open http://localhost:8100 in your browser, it should looks something similar to this.

Notice that I have opened my Chrome Dev Tools, and on the top left part, clicked on the devices Icon so that my app is displayed on a device screen. In this case, the Galaxy S5.

To see the app rendered in all mobile platforms, you can run

$ ionic serve -l

It should open your browser, but if not, visit http://localhost:8100/ionic-lab

We will almost always spend 90% of the time in the src folder, as that's where the application logic is. The whole app however is usually loaded from a simple src/index.html file, which during build is copied to a new folder www

We'll almost never touch this file. Notice the <ion-app></ion-app>: this is the entry point for our ionic app. It's called the root component of our app.

We'll see where it's defined shortly, but this is how Angular 2 apps are built. There is always a <root-component></root-component> kind of structure in the index.html page. The other parts of this file are just loading ionic build dependencies.

Another interesting part of this file is the service worker script tag that is commented out. Service Workers are out of scope for this tutorial, but they enable offline capabilities when it comes to web apps, and come in handy when building progressive web apps.

I'll briefly describe the other project structure.

- **config.xml** - This contains configurations like the app name, and the package name, that will be used to install our app into an actual device.
- **src** - This is where we'll spend the most of our time building our app. It contains the structured source code of our app.
- **node_modules** - Contains the npm packages listed in the **package.json** file. These are packages necessary for building the ionic app.
- **platforms** - This is where platform specific builds, build tools and packages/libraries are stored. You will find a folder for the platform your are building on. To add a platform, android for example, simply run `ionic platform add android`, and this will add the folder *android* folder to this folder.
- **plugins** - This is where [cordova plugins](http://https://cordova.apache.org/plugins/) will be stored when they are installed. Cordova plugins enables your app to have native functionality in the mobile device, e.g accessing the media storage of the device, or even the bluetooth API.
- **resources** - This also contains platform specific resources, such as icons and splash screens.

The src/app/app.component.ts is the root component of our app. It is loaded/declared in the src/app/app.module.ts, which simply represents our whole app as a module, which is the loaded in the app/main.dev.ts or app/main.prod.ts, depending on which build you do. This structure supports [Ahead of Time Compilation], an angular 2 feature that offloads compilation from the app bundle.

The src/app/app.html file is the root view for our application. In this case it holds a side menu.

If you are familiar with Angular 2, this should be straight foreward, if not, we'll cover some basics of this structure as we go.

An Ionic 2 app is usually divided into page components which are contained in the src/pages directory. You could think of them as what page is viewable on the screen at a particular given time (An Activity for Android Developers). The concept is actually interesting, because pages in ionic 2 are put in a stack, one on top of each other, and navigation back is as simple as removing the top most page in the stack (Last In First Out).

The src/themes folder contains sass files that help in theming the application.

Since we are using this Angular 2 module structure, we need to declare before hand all the components, providers, directives or pipes that our application uses. We will be adding these to this file as we go. You can see that this template imports all the pages it requires, adds the to the decalarations property of the @NgModule and also to the entryComponents property. This is also where we import our root component defined in the src/app/app.component.ts

Our Ionic App will have 3 main pages. One for github users, another for github organizations and another for github repositories. The last two pages are just views to show that we can navigate with the side bar, they will not have any content. The github users page, however, will enable you to view the details of the user.

Delete everything in the src/pages folder. Then we'll first quickly create the three main pages with help from the Ionic CLI. Run these in your terminal

This will create three folder with the respective names. g is an alias for generate, so you can still do ionic generate page pageName. Go into each of the folders and replace the content of the html files to look like this.

The ionViewDidLoad() method is an ionic life cycle hook. It's fired once an ionic view has load. Intuitive, right?

We'll then add these pages to our side nav. Go to src/app/app.component.ts and we'll make a few chages. If you check closely there is a class property called pages. This is what composes the sidenav (ion-menu) view, as show in the src/app/app.html

We will not touch this file too, we will just use it as it was generated. The button has an *ngFor="let p of pages" directive, this is how Angular 2 performs repeating in templates. It simply means loop through the pages collection and generate a template for each item in the collection. So if we change the value of the pages property, we change the content of the sidenav (ion-menu).

The <ion-nav> is where the page navigated to is displayed. The root property is bound to rootPage in the page class. We'll see definition this in detail shortly.

To add the correct pages in the sidenav, we'll make a few changes to the src/app/app.component.ts file. I have deleted two import statements (HelloIonicPage and ListPage) at the top for the pages we deleted, and added import statements for the pages we created.

The UsersPage, ReposPage and OrganisationsPage are component classes that represent the pages that were scaffolded when we generated the individual pages. You can check them out in src/pages/users/users.ts, src/pages/repos/repos.ts and src/pages/organisations/organisations.ts.

We'll then edit the pages class property to match our new pages.

src/app/app.component.ts

// imports commented out for brevityexportclassMyApp{
@ViewChild(Nav) nav: Nav;// make UsersPage the root (or first) page
rootPage:any= UsersPage;
pages:Array<{title:string, component:any}>;constructor(public platform: Platform,public menu: MenuController){this.initializeApp();// set our app's pagesthis.pages =[{ title:'Users', component: UsersPage },{ title:'Repos', component: ReposPage },{ title:'Organisations', component: OrganisationsPage },];}initializeApp(){this.platform.ready().then(()=>{// Okay, so the platform is ready and our plugins are available.// Here you can do any higher level native things you might need.
StatusBar.styleDefault();});}openPage(page){// close the menu when clicking a link from the menuthis.menu.close();// navigate to the new page if it is not the current pagethis.nav.setRoot(page.component);}}

Notice that the rootPage class property is set to the UsersPage. Remember that in the view src/app/app.html the <ion-nav> root property was bound to this rootPage. This means that the UsersPage will be shown first when the app loads.

We have changed the value of this.pages in the constructor to match the pages that we added.

The openPage method is responsible for opening pages when clicked. If you look back into the src/app/app.html, we can see that the list of pages of bound to this method with (click)="openPage(p)". Takes in a page, and opens it. Simple, right?

The final thing we need to do to finish this set up is tell angular about our pages. This is done in the src/app/app.module.ts file.

Import all the three pages and add them to both the declarations and the entryComponents properties of the @NgModule. Delete the imports we are not using

We've only included properties we'll need from a github response. Now that we have our model defined, we can create a github-users provider to enable us pull the users from github. To generate a provider run the following in your terminal

$ ionic g provider github-users

This creates a folder called providers in the src directory, and a github-users.ts file.

We need to add a method to get github users in the generated github-users.ts file.

The @Injectable() decorator is how Angular 2 declares it's services/providers.

The Observable import is necessary for because we will return the results of the github API call as an observable. Think of an observable as a stream of data we can subscribe to. We'll look at this in a bit more details shortly.

The first thing we did was to import the user model with import {User} from '../models/user'.

Then we add a function load which will return an Observable

We make a request to the github api, and parse the json response with res.json(), which we then cast as an array of users with <User[]>res.json(). This is returned as an observable, which we'll subscribe to to see the users.

To use our service in the whole app, we need to add it to the src/app/app.module.ts file.

First, we've imported the GithubUsers Provider at the top with import {GithubUsers} from '../../providers/github-users';. We've also import the User model.

In the constructor of our UsersPage, we've added githubUsers: GithubUsers as one of the parameters. This is how we inject dependencies in Angular 2. We then call the load function in the constructor and log the result with console.log.

Make sure ionic server is running, if not, run ionic serve in your terminal, then head over to https://localhost:81000, and open the console panel in Chrome Dev Tools .

You should see that an array of objects has been logged to our console, and on further inspection, it has almost all the properties of our user model.

To view the users in our view page, we need a local variable in the UserPage class that will be an array of Users. That is why we added users: User[], just after the class declaration. We'll assign it the the reponse of the githubUsers service call.

The items in the list have an ion-item directive which we will loop through with Angular 2's built in *ngFor template directive. We loop through all of the users with *ngFor="let user of users". users here refers to the UsersPage class property users

We then use property binding to load the avatar within ion-avatar, which just adds a rounded border to the image. Remember our user model had an avatar_url property, hence the user.avatar_url.

We then add the user's github username, which in this case is {{user.login}}.

The ion-icon is used for loading ionic icons. You simply give the name of the icon you'd like to use. In this case it's arrow-forward.

The item-right directive puts the icon to the far right of the list item.

Spin up the server if it's not running with ionic serve in your terminal, the head over to http://localhost:8100. You should see this.

First of all we import the UserDetailsPage at the top with import {UserDetailsPage} from '../user-details/user-details'.

We then add a method that will handle the navigation, goToDetails. It takes in a login (username) as a parameter.

Ionic 2 treats navigation as a stack, meaning pages are added on top of each other. That is why you see the this.navCtrl.push, and we push a page into the navigation stack. Going back or pressing the back button is like popping the last element in the stack (Last In First Out). The second parameter of the push is the object we wish to pass to the next page.

{login} is a es2015 property shorthand. In es5, this translates to {login: login}.

We've simply added NavParams to the existing imports to enable us access the navigation parameters.

Then, declared a login property of type string. Remember this represents the username.

We inject the NavParams provider in the constructor as navParams, which we then use to get the value of the passed parameter from the previous page with this.login = navParams.get('login') . This should update the user's login/username correctly in our details view.

If you go to http://localhost:8100, you should be able to click on a user and see this.

The username/login of the user you clicked should be the as a title in the view.

Get correct user details.

Now that we have the user in our details vew, we need to get his specific details. To do this we need to edit the GithubUsers provider to handle the request. The request will be made to https://api.github.com/users/{login}, where we pass in the username/login as the last parameter.

We've added an almost identical method to the initail load() called loadDetails(). It takes in a string login as a parameter and returns an Observable of User, that we can subscribe to, to get the results of the request. It casts the response to the User model with <User>res.json().

The http.get request is sent to ${this.githubApiUrl}/users/${login}. This is ES6 template strings, also available in typescript. It Involves using backticks, the key below the escape key on the keyboard, and passing any values with the ${var} syntax, and it will reolve to a valid string.

We've first of all imported the GithubUsers provider with import {GithubUsers} from '../../providers/github-users';.

We then import the user model with import {User} from '../../models/user';.

We then inject it in the constructor as githubUsers then call the githubUsers.loadDetails with the value retrieved from the navigation params login. We assign the resutls to the class property 'user', then log the results, just for debuggin purpose.

Go to http://localhost:8100, and click on a user, you should see this.

If you expand the logged object, you'll see it has the properties of our user model.

This is the final feature of our app. We'll start by adding a search box at the top of the users page. Ionic 2 provides a custom searchbar component and that's what we'll use.

src/pages/users/users.html

<!--HTML commented out for brevity--><ion-contentpadding><ion-searchbar></ion-searchbar><ion-list><!--HTML commented out for brevity--></ion-list></ion-content>

We've added a search bar with <ion-searchbar>, and should have a searchbar at the top of the page.

The logic behind searching is simple. Since we have a list already, we'll just update the list with our result. The github api enables you to search through the following url structure https://api.github.com/search/users?q={searchParam}, with a searchParam.

We'll first of all create a provider method for search in our GithubUsers Provider. The method is also almost similar to the load() method.

We've added an originalUsers class property, to cache the original results of the github users fetch.

Our search function is structured to only work when the search parameter is of character length that is grater than 3. We reset the results if this condition is not met. (This is not robust however, because the user can enter non-alphanumeric characters, but for learning purposes, will do).

Go to http://localhost:8100, and try searching for a term, or a username you know.
Clicking any of the result should take you to that user's profile.

Building Ionic 2 Apps is pretty intuitive and cleaner once you have an understanding of how Angular 2 works. Ionic handles its views as components. You can build an application really quickly, especially if you have your api already defined somewhere.

I think Ionic plays a major role, especially in the development of Progressive Web Apps. If anyone is looking to invest some time in them, they should definitely give Ionic a shot.

Jobs!

Most JavaScript frameworks these days usually have some sort of Command Line Interface (CLI) that enables users quickly scaffold applications and get straight to building apps, without doing repetitive set up tasks. Some common ones are: Vue CLI...