Nikola Brežnjak blog - Tackling software development with a dose of humor
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Home
Daily Thoughts
Ionic
Stack Overflow
Books
About me
  • Home
  • Daily Thoughts
  • Ionic
  • Stack Overflow
  • Books
  • About me
Nikola Brežnjak blog - Tackling software development with a dose of humor
Ionic

How to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin

In this tutorial, I’m going to show you how to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin that’s originally made for Ionic 2 and Ionic 3. Hopefully, I’ll save you some time so that you won’t have to figure this out on your own. I’ll note where the official documentation is lacking in terms of setting the correct link when passing additional parameters.

So, let’s get started!

Demo project

You can check out the code for this project on Github.

Here’s the app in action, where you’ll notice how by clicking the link you are taken to the app to a specific screen. Also, additional nesting (opening up the detail screen of one ‘chat’) also works:

Step by step

Here are the steps you can take to get to the same final working project like the one I’ve posted on Github.

Start a new Ionic 1 project based on tabs template:

ionic start IonicDeeplinkTest tabs

Add the deeplinks plugin:

ionic plugin add ionic-plugin-deeplinks --variable URL_SCHEME=nikola --variable DEEPLINK_SCHEME=http --variable DEEPLINK_HOST=nikola-breznjak.com --save

Few things to note here are:

  • URL_SCHEME – a string which you’ll put in your links so that once clicked your phone’s operating system will know to open your app. In my case, the links will look like nikola://something
  • DEEPLINK_SCHEME – most probably you’ll want to put https here, but I’ve put http because my website doesn’t (yet) have SSL support ?
  • DEEPLINK_HOST – you should put your domain here on which you’ll put the link

The output of the command above should be something like this:

Fetching plugin "ionic-plugin-deeplinks" via npm

Installing "ionic-plugin-deeplinks" for ios

Installing dependency packages: 

{
  "mkpath": ">=1.0.0",
  "xml2js": ">=0.4",
  "node-version-compare": ">=1.0.1",
  "plist": ">=1.2.0"
}

Now, as mentioned in the official plugin docs, this plugin is originally provided through Ionic Native for Ionic 2+ apps. But, we can use Ionic Native with Ionic 1 if we install it like this (official docs on this subject):

npm install ionic-native --save

Now, copy ionic.native.min.js from node_modules/ionic-native/dist folder into a new lib/ionic-native folder.

Then, in index.html add:

<script src="lib/ionic-native/ionic.native.min.js"></script>

just before the

<script src="cordova.js"></script>

line.

Next, run the following command:

npm install --save @ionic-native/deeplinks

Finally, open up the app.js file and add the following code inside the platform.ready callback:

$cordovaDeeplinks.route({
    '/chats/:chatId': {
        target: 'tab.chat-detail',
        parent: 'tab.chats'
    },
    '/account': {
        target: 'tab.account',
        parent: 'tab.account'
    },
    '/chats': {
        target: 'tab.chats',
        parent: 'tab.chats'
    }
}).subscribe(function(match) {
    $timeout(function() {
        $state.go(match.$route.parent, match.$args);

        if (match.$route.target != match.$route.parent) {
            $timeout(function() {
                $state.go(match.$route.target, {chatId: match.$args.chatId});
            }, 800);
        }
    }, 100); // Timeouts can be tweaked to customize the feel of the deeplink
}, function(nomatch) {
    console.warn('No match', nomatch);
});

Also, don’t forget to add ionic.native to the angular.module function in the app.js file:

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ionic.native'])

and inject $cordovaDeeplinks in the .run function.

Just for reference, the full contents of the app.js file should now look like this:

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ionic.native'])

.run(function($ionicPlatform, $cordovaDeeplinks, $timeout, $state) {
    $ionicPlatform.ready(function() {
        // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
        // for form inputs)
        if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
            cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
            cordova.plugins.Keyboard.disableScroll(true);

        }
        if (window.StatusBar) {
            // org.apache.cordova.statusbar required
            StatusBar.styleDefault();
        }

        $cordovaDeeplinks.route({
            '/chats/:chatId': {
                target: 'tab.chat-detail',
                parent: 'tab.chats'
            },
            '/account': {
                target: 'tab.account',
                parent: 'tab.account'
            },
            '/chats': {
                target: 'tab.chats',
                parent: 'tab.chats'
            }
        }).subscribe(function(match) {
            console.log('matching');
            console.dir(match);
            $timeout(function() {
                $state.go(match.$route.parent, match.$args);

                if (match.$route.target != match.$route.parent) {
                    $timeout(function() {
                        $state.go(match.$route.target, {chatId: match.$args.chatId});
                    }, 800);
                }
            }, 100); // Timeouts can be tweaked to customize the feel of the deeplink
        }, function(nomatch) {
            console.warn('No match', nomatch);
            console.dir(nomatch);
        });
    });
})

.config(function($stateProvider, $urlRouterProvider) {

    // Ionic uses AngularUI Router which uses the concept of states
    // Learn more here: https://github.com/angular-ui/ui-router
    // Set up the various states which the app can be in.
    // Each state's controller can be found in controllers.js
    $stateProvider

    // setup an abstract state for the tabs directive
        .state('tab', {
        url: '/tab',
        abstract: true,
        templateUrl: 'templates/tabs.html'
    })

    // Each tab has its own nav history stack:

    .state('tab.dash', {
        url: '/dash',
        views: {
            'tab-dash': {
                templateUrl: 'templates/tab-dash.html',
                controller: 'DashCtrl'
            }
        }
    })

    .state('tab.chats', {
            url: '/chats',
            views: {
                'tab-chats': {
                    templateUrl: 'templates/tab-chats.html',
                    controller: 'ChatsCtrl'
                }
            }
        })
        .state('tab.chat-detail', {
            params: {chatId: 0},
            url: '/chats/:chatId',
            views: {
                'tab-chats': {
                    templateUrl: 'templates/chat-detail.html',
                    controller: 'ChatDetailCtrl'
                }
            }
        })

    .state('tab.account', {
        url: '/account',
        views: {
            'tab-account': {
                templateUrl: 'templates/tab-account.html',
                controller: 'AccountCtrl'
            }
        }
    });

    // if none of the above states are matched, use this as the fallback
    $urlRouterProvider.otherwise('/tab/dash');
});

A few example links that you should put on your website look like this:

<a href="nikola://account">Open Account</a>
<a href="nikola://chats">Open Chats</a>
<a href="nikola://app/chats/4">Open chat detail 4</a>

I created a simple demo page so you can test this if you’d like and it’s here. Just open this link on your phone, after you’ve run the demo app on your phone and you should see the links working – meaning; taking you to proper sections in the app.

Just for reference, the contents of that file is this:

<!DOCTYPE html>
<html>
<head>
    <title>Deeplinking test</title>

    <style type="text/css">
        a {
            font-size: 80px;
            margin: 40px;
            display: block;
        }

        body {
            text-align: center;
        }
    </style>
</head>
<body>
    <a href="nikola://account">Open Account</a>

    <a href="nikola://chats">Open Chats</a>

    <a href="nikola://app/chats/4">Open chat detail 4</a>
</body>
</html>

The most important part here, on which I’ve wasted most of the time is the nikola://app/chats/4 part. Namely, at first I expected that you only should write it as nikola://chats/4, but by finding the bug report about this in the official repo I realized that you have to put something as a suffix (I’ve put app here).

Now, to run the app on your device, first prepare it:

ionic prepare ios

Then, open the platforms/ios/IonicDeeplinkTest.xcodeproj file:

And, make sure the string nikola (of course, change this string to your use case – usually the name of the app) is set as shown on the image:

For any potential additional info about setting up Xcode, check the official blog post.

Here’s the app in action, where you’ll notice how by clicking the link you are taken to the app to a specific screen. Also, additional nesting (opening up the detail screen of one ‘chat’) also works by passing in the argument.

Conclusion

I hope this was helpful and that it saved you some time in trying to figure this out.

In case you’re wondering how to do this for Ionic 2, 3+ apps, then it’s even easier as shown in the official docs.

How to use deep linking in Ionic 1 apps with Ionic Native Deeplinks plugin https://t.co/dAtt4Fwv3o

— Nikola Brežnjak (@HitmanHR) August 25, 2017

Ionic3

How to create icons and splash screen images automatically in Ionic framework 3

⚠️ In case you’re looking for how to create icons and splash screen images automatically in Ionic framework version 1, then you can check out this post. For more Ionic framework 3 posts check out the step by step info on How to get started with Ionic framework 3 on Windows and Mac.

TL;DR

Just execute ionic cordova resources command in your Ionic 3 project root folder.

!TL;DR

The icon is an important part of your application because it represents your application’s brand, and it helps to identify quickly where the app is on your phone. In case you’re familiar with creating apps then you will remember that it is a tedious process to create a lot of different size images both for iOS and Android platforms.

Also, the same goes for the so-called splash screen that shows up every time the application starts. Although having a splash screen is not mandatory, it certainly adds up to the feeling of a complete and professional application, which one would certainly want to convey with his application.

Ionic helps tremendously with this by providing a single Ionic CLI command to generate all the needed icon and splash screen sizes for us automatically. Also, Ionic created Photoshop Splash Screen Template, which you can download for free and use as a guideline for creating an icon. However, if you create you project by using ionic start command, as we have, then you’ll already have both the icon.png and splash.png files in the resources folder, and you can just edit them.

For when you’re creating a branded product having a custom made icon is definitely a must. However, in this case, I’ll show you how to use one of the free services to search for a free icon which you can then use in your application (even if your application is a commercial application).

I tend to use IconFinder a lot, and here are the settings which you have to use to filter out the calculator images that are Free (PRICE) and can be used in commercial applications and that don’t even require a link back (LICENSE TYPE).

Of course, you can also choose to buy an image if you happen to find one that you like. You can additionally search by format, size, and background. The filters should look like this (or use this prepared link which sets them automatically):

I’m going to use the last one in the first row. Simply click on it, and you should get to the download page that looks like this:

To download it just click on the green ‘Download PNG’ button.

Now, in the resources folder find and open the icon.png file with an image editor of your choice. I’m going to use Gimp in this example as it’s free cross-platform image editor available for all the major operating systems (Linux, OS X, Windows). You should see something like this:

Now we need to do a few steps:

  • select the whole area (Ctrl + a or Command + a) and press the DEL button on your keyboard. This should leave you with a blank white canvas.
  • drag the calculator icon on this white canvas and you should see something like this:
  • click on the scale tool
  • then click on the calculator image. You should get this popup:
  • change the values in the popup to 1024px for both Width and Height and click the Scale button.
  • click on the Alignment Tool, then click on the calculator image and then on the circled two buttons on the image below. This will align the calculator image horizontally and vertically

Now save the file by going to File->Overwrite icon.png:

Repeat the process to create the splash screen image and name it (overwrite it as) splash.png. The image I came up with looks like this:

Now that you have both icon.png and splash.png images ready navigate with your Terminal/Command prompt to the root folder of the application and run the following command:

ionic cordova resources

If at this point you get an error like this:

[ERROR] No platforms have been added. Please run: ionic cordova platform add

That means that you haven’t added any platforms yet to which Ionic should build. Since we’re going to build the app for both Apple Store and Android Play Store we’re going to use the following two commands:

ionic cordova platform add android
ionic cordova platform add ios

You should see an output similar to this:

ionic cordova platform add ios
> cordova platform add ios --save
✔ Running command - done!
Using cordova-fetch for cordova-ios@~4.4.0
Adding ios project...
Creating Cordova project for the iOS platform:
    Path: platforms/ios
    Package: io.ionic.starter
    Name: MyApp
iOS project created with [email protected]
Discovered plugin "cordova-plugin-console" in config.xml. Adding it to the project
Installing "cordova-plugin-console" for ios
Adding cordova-plugin-console to package.json
Saved plugin info for "cordova-plugin-console" to config.xml
Discovered plugin "cordova-plugin-device" in config.xml. Adding it to the project
Installing "cordova-plugin-device" for ios
Adding cordova-plugin-device to package.json
Saved plugin info for "cordova-plugin-device" to config.xml
Discovered plugin "cordova-plugin-splashscreen" in config.xml. Adding it to the project
Installing "cordova-plugin-splashscreen" for ios
Adding cordova-plugin-splashscreen to package.json
Saved plugin info for "cordova-plugin-splashscreen" to config.xml
Discovered plugin "cordova-plugin-statusbar" in config.xml. Adding it to the project
Installing "cordova-plugin-statusbar" for ios
Adding cordova-plugin-statusbar to package.json
Saved plugin info for "cordova-plugin-statusbar" to config.xml
Discovered plugin "cordova-plugin-whitelist" in config.xml. Adding it to the project
Installing "cordova-plugin-whitelist" for ios
Adding cordova-plugin-whitelist to package.json
Saved plugin info for "cordova-plugin-whitelist" to config.xml
Discovered plugin "ionic-plugin-keyboard" in config.xml. Adding it to the project
Installing "ionic-plugin-keyboard" for ios
Adding ionic-plugin-keyboard to package.json
Saved plugin info for "ionic-plugin-keyboard" to config.xml
--save flag or autosave detected
Saving ios@~4.4.0 into config.xml file ...
✔ Copying default image resources into ./resources/ios - done!

> cordova platform add android --save
✔ Running command - done!
Using cordova-fetch for cordova-android@~6.2.2
Adding android project...
Creating Cordova project for the Android platform:
    Path: platforms/android
    Package: io.ionic.starter
    Name: MyApp
    Activity: MainActivity
    Android target: android-25
Subproject Path: CordovaLib
Android project created with [email protected]
Installing "cordova-plugin-console" for android
Installing "cordova-plugin-device" for android
Installing "cordova-plugin-splashscreen" for android
Installing "cordova-plugin-statusbar" for android
Installing "cordova-plugin-whitelist" for android

               This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do *not* need this plugin since the whitelist will be built in.

Installing "ionic-plugin-keyboard" for android
--save flag or autosave detected
Saving android@~6.2.3 into config.xml file ...
✔ Copying default image resources into ./resources/android - done!

After this, you can safely run the ionic cordova resources command, and you should get the following output:

✔ Collecting resource configuration and source images - done!
✔ Filtering out image resources that do not need regeneration - done!
✔ Uploading source images to prepare for transformations - done!
✔ Generating platform resources: 48 / 48 complete - done!
✔ Modifying config.xml to add new image resources - done!

From the output, you can see that 48 images were created and hopefully now you realize how much time this saved. All the needed configuration regarding the icons and splash screens was generated by Ionic and placed in the config.xml file.

It’s worth noting that you will not see the icon nor the splash screen when using the browser testing or Ionic View testing. Instead, you will only see these once you deploy them to the actual physical device or the emulator.

⚠️ You can add an iOS platform if you’re developing on a Windows machine, and ionic cordova resources command will generate icons and splash screens for it. However, keep in mind that you will not be able to build the project for iOS on your Windows machine. Instead, you’ll need a Mac computer to do so.

How to create icons and splash screen images automatically in Ionic framework 3 @ionicframework https://t.co/EKe3QDeo8E

— Nikola Brežnjak (@HitmanHR) August 23, 2017

Programming

Code Complete 2 – Steve McConnell – Working Classes

I just love Steve McConnell’s classic book Code Complete 2, and I recommend it to everyone in the Software ‘world’ who’s willing to progress and sharpen his skills.

Other blog posts in this series:

  • Part 1: Laying the Foundation
  • Chapter 5: Design in Construction

Class Foundations: Abstract Data Types (ADTs)

An abstract data type is a collection of data and operations that work on that data. The operations both describe the data to the rest of the program and allow the rest of the program to change the data.
For example, if you are not using ADTs to change a bold property of text you could write something like:

currentFont.bold = true;

but a better way, which keeps the abstraction of the class, is:

currentFont.SetBoldOn();

It ain’t abstract if you have to look at the underlying implementation to understand what’s going on. ~ P.J. Plauger

By thinking about ADT, and not about classes, we are programming into the language and not programming in language.

If a stack represents a set of employees, treat the ADT as employees rather than as a stack. Treat yourself to the highest possible level of abstraction.

Try to make the names of classes and access routines independent of how the data is stored.

For example:

game.save()

is better than

game.saveDataInFile()

One way to think of a class is as an abstract data type plus inheritance and polymorphism.

Good class interface

The first and probably most important step in creating a high-quality class is creating a good interface. This consists of creating a good abstraction for the interface to represent and ensuring the details remain hidden behind the abstraction.

If the class interface doesn’t present a consistent abstraction, then the class has poor cohesion.

Class interface consists of public routines (functions, methods)

Each class should implement one ADT!

In some cases, you’ll find that half a class’s routines work with half the class’s data, and half the routines work with the other half of the data. In such a case, you really have two classes masquerading as one. Break them up!

Move unrelated information to another class

Good Encapsulation

Encapsulation is a stronger concept than abstraction.
Abstraction helps to manage complexity by providing models that allow you to ignore implementation details. Encapsulation is the enforcer that prevents you from looking at the details even if you want to.

Don’t expose member data in public

You shouldn’t expose data like this:

float x;
float y;

because client code can monkey around with data. And perfect encapsulation would look like:

float GetX();
float GetY();
void SetX( float x );
void SetY( float y );

Now you have no idea whether the underlying implementation is in terms of floats x, y, whether the class is storing those items as doubles and converting them to floats, or whether the class is storing them on the moon and retrieving them from a satellite in outer space. ?

Avoid friend classes

In a few circumstances such as the State pattern, friend classes can be used in a disciplined way that contributes to managing complexity. But, in general, friend classes violate encapsulation. They expand the amount of code you have to think about at any one time, increasing complexity.

Design and Implementation Issues

Containment (“has a” Relationships)

Containment is a simple idea that a class contains a primitive data element or object. A lot more is written about inheritance than about containment, but that’s because inheritance is more tricky and error prone, not because it’s better.

Inheritance (“is a” Relationships)

Don’t inherit a class instead it’s a truly “is a” more specific version of the Base Class. ~ Barbara Liskov

Inherited routines come in three basic flavors:
+ An Abstract overridable routine means that the derived class inherits the routine’s interface but not its implementation.
+ Overridable routine means that the derived class inherits the routine’s interface but not its implementation

Overridable routine -> polymorphism
+ A non-overridable routine means that the derived class inherits the routine’s interface and its default implementation and it is not allowed to override the routine’s implementation

Don’t reuse names of non-overridable base-class routines in derived classes.

Avoid deep inheritance trees

Deep inheritance trees have been found to be significantly associated with increased fault rates. That’s because of deep inheritance trees increase complexity, which is exactly the opposite of what inheritance should be used to accomplish.

7±2 subclasses from base class, and maximum of three levels of inheritance

Rules for inheritance

  • If multiple classes share common data but not behavior, create a common object that those classes can contain.
  • If multiple classes share common behavior but not data, derive them from a common base class that defines the common routines.
  • If multiple classes share common data and behavior, inherit from a common base class that defines the common data and routines.
  • Inherit when you want the base class to control your interface; contain when you want to control your interface.

Law of Demeter

The rule states that Object A can call any of its own routines. If Object A instantiates an Object B, it can call any of Object B’s routines. But it should avoid calling routines on objects provided by Object B.

Constructors

Initialize all member data in all constructors, if possible. Initializing all data member in all constructors is an inexpensive defensive programming practice.

Enforce the singleton property by using a private constructor. If you want to define a class that allows only one object to be instantiated, you can enforce this by hiding all the constructors of the class and then providing a static GetInstance() routine to access the class’s single instance.

Deep and shallow copy

  • Deep copies are simpler to code and maintain than shallow copies
  • Shallow copies are created typically to improve performance

Prefer deep copies to shallow copies until proven otherwise.

Reasons to Create a Class

Create a class to hide information so that you won’t have to think about it and to reduce complexity. Sure, you will need to think about it when you write the class, but after it’s written you can forget about the implementation details and use the class without any knowledge of its internal workings.

Key points

  • Class interface should provide a consistent abstraction. Many problems arise from violating this single principle.
  • Classes must have data members and behavior
  • Containment is usually preferable to inheritance unless you’re modeling an “is a “relationship
  • Inheritance is a useful tool, but it adds complexity, which is counter to Software’s Primary Technical Imperative of managing complexity

My #notes from the classic Code Complete 2 #book by Steve McConnell chapter 5: Working Classes https://t.co/aWK3uWdBUr

— Nikola Brežnjak (@HitmanHR) August 21, 2017

Books

Flowers for Algernon – Daniel Keyes

My favorite quotes from the book Flowers for Algernon by Darren Hardy which I rated 5/5 on my Goodreads account. Lately, I haven’t been reading any nonfiction books, but this was a great one to start with again.

Now I understand that one of the important reasons for going to college and getting an education is to learn that the things you’ve believed in all your life aren’t true, and that nothing is what it appears to be.

It’s easy to make friends if you let people laugh at you.

Intelligence is one of the greatest human gifts. But all too often a search for knowledge drives out the search for love. This is something else I’ve discovered for myself very recently. I present it to you as a hypothesis: Intelligence without the ability to give and receive affection leads to mental and moral breakdown, to neurosis, and possibly even psychosis. And I say that the mind absorbed in and involved in itself as a self-centered end, to the exclusion of human relationships, can only lead to violence and pain.

A child may not know how to feed itself, or what to eat, yet it knows hunger.

Strange about learning; the farther I go the more I see that I never knew even existed. A short while ago I foolishly thought I could learn everything – all the knowledge in the world. Now I hope only to be able to know of its existence, and to understand one grain of it. Is there time?

There are a lot of people who will give money or materials, but very few who will give time and affection.

No one really starts anything new, Mrs. Nemur. Everyone builds on other men’s failures. There is nothing really original in science. What each man contributes to the sum of knowledge is what counts.

 …the men of the cave would say of him that up he went and down he came without his eyes.

My favorite #quotes from the #book Flowers for Algernon by Daniel Keyes https://t.co/D37Vesvknj

— Nikola Brežnjak (@HitmanHR) August 21, 2017

Ionic3

How to make money with Google AdMob ads in Ionic framework 3

In case you’re looking for a way to implement Google AdMob ads in Ionic framework 1, then check out this tutorial: Adding AdMob to Ionic framework application step by step.

Introduction

There are multiple ways you can earn money with your app these days and here are just a few of them:

  • Paid app – set a price for your app directly on the App/Play Store that users need to pay before downloading your app
  • Freemium – give the app for free but charge for in-app purchases like adding some extra features (think more gold or faster production in game apps)
  • Ad-based – show ads inside your application. Potentially offer the in-app purchase to remove the ads

In this post, I’m going to cover the Ad-based monetization option, and I’ll show you how to add Google AdMob ads to a simple Ionic 3 blank template application. There are two parts to implementing Google AdMob ads to an Ionic project and I broke them into: AdMob settings and Ionic settings.

Demo app and repo

You can check the final code on Github. When you clone it, run npm install inside the project. In case you have your development machine set up for Ionic, then you can run the project with ionic emulate ios or ionic emulate android. If you don’t but would like to, see this post on How to get started with Ionic framework 3 on Mac and Windows.

You should see something like this in your simulator/emulator:

AdMob settings

Let’s start with AdMob settings:

  1. Sign in/Sign up for AdMob at https://www.google.com/admob/
  2. Click the Apps and then ADD APP button:

  1. Since our app is not published yet we will click the No button:

  1. Fill in the app name and platform and click the ADD button:

  1. Save the App ID somewhere and proceed to create the Ad unit

  1. Select Banner Ad format:

  1. Configure the adds type, size, placement, style, name:

  1. You can read additional info on how to implement GA and AdMob, but for now let’s just click Done:

  1. You will now see the following similar screen:

The most important thing to note here is this Ad unit ID, which in my test case is ca-app-pub-7957971173858308/5068937357. Make a note of this string as it’s the most important part of this setting. You can click on the copy to clipboard button and paste it as a comment (for now) in your app.

  1. Create as much Ad units as you may need (for each platform[iOS, Android] and ad format [Banner, Interstitial, etc.]). In my case, I just created the additional Interstitial Ad and will use them on both iOS and Android devices for the purpose of this demo.

Ionic settings

Those of you familiar with Ionic 1 know that you can add any plugin to your Ionic project thanks to the project called ngCordova. For Ionic 3, there’s the same thing called Ionic Native.

Ionic Native is a TypeScript wrapper for Cordova/PhoneGap plugins that makes it easy to add any native functionality that you may need into your Ionic app. Ionic Native wraps the plugin callbacks in a Promise or an Observable, providing a common interface for all plugins and ensuring that native events trigger change detection in Angular.

First, let’s start an empty Ionic 3 application based on the blank template:

ionic start Ionic3AdMobTest blank --cordova

You should see the following output:

✔ Creating directory ./Ionic3AdMobTest - done!
[INFO] Fetching app base (https://github.com/ionic-team/ionic2-app-base/archive/master.tar.gz)
✔ Downloading - done!
[INFO] Fetching starter template blank (https://github.com/ionic-team/ionic2-starter-blank/archive/master.tar.gz)
✔ Downloading - done!
✔ Updating package.json with app details - done!
✔ Creating configuration file ionic.config.json - done!
[INFO] Installing dependencies may take several minutes!
> npm install
✔ Running command - done!
> npm install --save-dev --save-exact ionic@latest
✔ Running command - done!
> npm install --save-dev --save-exact @ionic/cli-plugin-ionic-angular@latest
✔ Running command - done!
> npm install --save-dev --save-exact @ionic/cli-plugin-cordova@latest
✔ Running command - done!
> npm dedupe
✔ Running command - done!
> git init
✔ Running command - done!
> git add -A
✔ Running command - done!
> git commit -m "Initial commit" --no-gpg-sign
✔ Running command - done!

♬ ♫ ♬ ♫  Your Ionic app is ready to go! ♬ ♫ ♬ ♫

Run your app in the browser (great for initial development):
  ionic serve

Run on a device or simulator:
  ionic cordova run ios

Test and share your app on a device with the Ionic View app:
  http://view.ionic.io


Next Steps:
Go to your newly created project: cd ./Ionic3AdMobTest

Navigate to the root of the application with your Terminal/Command prompt and execute the following command to add the cordova-plugin-admobpro plugin:

ionic cordova plugin add cordova-plugin-admobpro

You should see the following output after running the command:

✔ Running command - done!
Adding cordova-plugin-admobpro to package.json
Saved plugin info for "cordova-plugin-admobpro" to config.xml

Additionally, you will also need to run this command:

npm install --save @ionic-native/admob-pro

which, if completed successfully, will only output something like added 1 package in 3.331s to the console.

You need to add this second command as well because this installs some files needed by TypeScript.

⚠️ At this point, depending on the version of Ionic CLI that you have you may need to add a platform by executing: ionic cordova platform add ios or ionic cordova platform add android depending on the platform you’re trying to build for. You have to execute that if the command ionic cordova platform ls shows that you don’t have any installed platforms on the current project:

→ ionic cordova platform ls
✔ cordova platform ls - done!
Installed platforms:
Available platforms: 
 android ~6.2.2
 blackberry10 ~3.8.0 (deprecated)
 browser ~4.1.0
 ios 4.4.0
 osx ~4.0.1
 webos ~3.7.0

If everything is fine with running ionic cordova platform add ios you will see an output like this:

Using cordova-fetch for cordova-ios@~4.4.0
Adding ios project...
Creating Cordova project for the iOS platform:
    Path: platforms/ios
    Package: io.ionic.starter
    Name: MyApp
iOS project created with [email protected]
Installing "cordova-plugin-admobpro" for ios
Installing "cordova-plugin-extension" for ios
Discovered plugin "cordova-plugin-console" in config.xml. Adding it to > the project
Installing "cordova-plugin-console" for ios
Adding cordova-plugin-console to package.json
Saved plugin info for "cordova-plugin-console" to config.xml
Discovered plugin "cordova-plugin-device" in config.xml. Adding it to > the project
Installing "cordova-plugin-device" for ios
Adding cordova-plugin-device to package.json
Saved plugin info for "cordova-plugin-device" to config.xml
Discovered plugin "cordova-plugin-splashscreen" in config.xml. Adding > it to the project
Installing "cordova-plugin-splashscreen" for ios
Adding cordova-plugin-splashscreen to package.json
Saved plugin info for "cordova-plugin-splashscreen" to config.xml
Discovered plugin "cordova-plugin-statusbar" in config.xml. Adding it > to the project
Installing "cordova-plugin-statusbar" for ios
Adding cordova-plugin-statusbar to package.json
Saved plugin info for "cordova-plugin-statusbar" to config.xml
Discovered plugin "cordova-plugin-whitelist" in config.xml. Adding it > to the project
Installing "cordova-plugin-whitelist" for ios
Adding cordova-plugin-whitelist to package.json
Saved plugin info for "cordova-plugin-whitelist" to config.xml
Discovered plugin "ionic-plugin-keyboard" in config.xml. Adding it to > the project
Installing "ionic-plugin-keyboard" for ios
Adding ionic-plugin-keyboard to package.json
Saved plugin info for "ionic-plugin-keyboard" to config.xml
--save flag or autosave detected
Saving ios@~4.4.0 into config.xml file ...
✔ Copying default image resources into ./resources/ios - done!

Btw, there is also a free version of the AdMob Pro plugin. But, honestly, if you really start making money with your app, this will be a minor expense. Besides, if you’re having problems giving back to the actual plugin through which you’re making money then my dear padawan you have yet much to learn…

Now, let’s add this plugin to our app’s NgModule. In the src/app/app.module.ts file import AdmobPro:

import { AdMobPro } from '@ionic-native/admob-pro';

and then add it to the Providers array. The whole contents of the src/app/app.module.ts file should now looks like this:

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';

import { AdMobPro } from '@ionic-native/admob-pro';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

@NgModule({
    declarations: [
        MyApp,
        HomePage
    ],
    imports: [
        BrowserModule,
        IonicModule.forRoot(MyApp)
    ],
    bootstrap: [IonicApp],
    entryComponents: [
        MyApp,
        HomePage
    ],
    providers: [
        StatusBar,
        SplashScreen,
        AdMobPro,
        { provide: ErrorHandler, useClass: IonicErrorHandler }
    ]
})
export class AppModule { }

Now I’m going to show you the final content of the src/pages/home/home.ts file and will explain what was changed step by step:

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

import { AdMobPro } from '@ionic-native/admob-pro';
import { Platform } from 'ionic-angular';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
export class HomePage {
    constructor(public navCtrl: NavController, platform: Platform, private admob: AdMobPro) {
        platform.ready().then(() => {
            var admobid = {
                banner: 'ca-app-pub-7957971173858308/5068937357',
                interstitial: 'ca-app-pub-7957971173858308/5667703151'
            };

            this.admob.createBanner({
                adId: admobid.banner,
                isTesting: true,
                autoShow: true,
                position: this.admob.AD_POSITION.BOTTOM_CENTER
            })

            this.admob.prepareInterstitial({
                adId: admobid.interstitial,
                isTesting: true,
                autoShow: false
            })
        });
    }

    showInterstitialAd() {
        if (AdMobPro) {
            this.admob.showInterstitial();
        }
    }
}

First, we added the imports:

import { AdMobPro } from '@ionic-native/admob-pro';
import { Platform } from 'ionic-angular';

Then, via the constructor we injected Platform and AdMobPro:

constructor(public navCtrl: NavController, platform: Platform, private admob: AdMobPro)

Then we wrapped everything in the platform.ready() promise. This is the most important part of the code! If you wouldn’t do that, it could happen that your app would start up and the plugins would still not be properly set up, and you wouldn’t see the ads displayed.

But then again, sometimes you would, and this is what it would make it a nightmare to debug. This is a very common issue that I’ve seen even back from Ionic 1 when answering the questions on StackOverflow. So, you may want to keep an ?️ on the fact that you need to wrap any plugin calls inside the platform.ready() promise, as that way you’ll be sure that all of the plugins have loaded before you’ll use them.

The code that’s executed after the promise resolves sets up our admobid object with banner and interstitial properties. Then we’re calling the createBanner and prepareInterstitial functions on the injected admob object. Note how the banner is set to show automatically when the app loads (autoShow: true) and the interstitial isn’t. Also, note how we’ve set the position of the banner ad to the bottom:

platform.ready().then(() => {
    var admobid = {
        banner: 'ca-app-pub-7957971173858308/5068937357',
        interstitial: 'ca-app-pub-7957971173858308/5667703151'
    };

    this.admob.createBanner({
        adId: admobid.banner,
        isTesting: true,
        autoShow: true,
        position: this.admob.AD_POSITION.BOTTOM_CENTER
    })

    this.admob.prepareInterstitial({
        adId: admobid.interstitial,
        isTesting: true,
        autoShow: false
    })
});

Then we added the showshowInterstitialAdAd function, which shows the Interstitial ad:

showInterstitialAd() {
    if (AdMobPro) {
        this.admob.showInterstitial();
    }
}

Of course, at this point, change the admobid object properties to your AdMob keys which you obtained in the first part (step 9).

? If you run into any problems with this, just ping in the comments, and I’ll do my best to help you.

One common thing that you might have to do for Android is to install some extras via the Android SDK manager. To do so open Android Studio and select Configure->SDK Manager:

Make sure you have installed the packages marked as Installed on the image below (usually, those are Google Billing Library and Google Play services):

What kind of an ad should you show?

This plugin’s documentation states an interesting fact that it’s strongly recommended to use the Interstitial ad type because it brings more than 10 times profit than the banner Ad. Here’s the table from the official documentation:

Ad Format Banner Interstitial
Click Rate < 1% 3-15%
RPM (1k impressions) 0.5$ – 4$ 10-50$

Banner ad is the small add that is usually placed in the bottom of the screen, whereas Interstitial ads are full-screen ads that cover the interface of their host app. Therefore, you may rather want to opt for this kind of an ad instead for the Banner one.

It’s important to note that there’s probably no exact formula here on when to show the Interstitial Ad, but there are some best practices, and this is what Google has to say about it:

Interstitial ads work best in apps with natural transition points. The conclusion of a task within an app, like sharing an image or completing a game level, creates such a point. Because the user is expecting a break in the action, it’s easy to present an interstitial without disrupting their experience. Make sure you consider at which points in your app’s workflow you’ll display interstitials, and how the user is likely to respond.

You can learn a bit more about it here.

Anyways, as you saw in our demo code above, we opted for showing the banner ad all the time in the bottom of the screen, and we’re showing the interstitial ad when we click the button. You can tweak this any way you like in your app, but please remember the points mentioned above about best practices.

Finally, the view template

Replace the src/pages/home/home.html file content with this:

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

<ion-content padding>
    <button ion-button (click)="showInterstitialAd()">Show the interstitial Ad</button>
</ion-content>

Clicking the Show the interstitial Ad button will call the showInterstitialAd() function which will show the interstitial as shown in a gif at the beginning of this tutorial.

Let’s test this

Run ionic cordova emulate ios and in a few seconds your simulator should start up and show you this:

There are few things that could go wrong with this, so for example if you get an error like this:

Error: Cannot read property 'replace' of undefined

[ERROR] Cordova encountered an error.
        You may get more insight by running the Cordova command above directly.

[ERROR] An error occurred while running cordova run ios (exit code 1).

Then you can try the solution from this StackOverflow post: Execute the following command in the platforms/ios/cordova/node_modules folder: sudo npm install ios-sim@lates.

If you get an error telling you that it can’t open up the simulator, then you may want to try running the build command: ionic cordova build ios and after that open the MyApp.xcworkspace file from the platforms/ios folder:

Select the simulator device that you’d like to run your app on and click the run button from your Xcode:

If you run into any other problems while trying to run this, let’s try to solve them in the comments and thus help others that may have the same issues as well ?

Conclusion

In this post, we’ve shown how easy it is to add monetization options to your app. Now it’s ‘just’ on you to actually make an app that will be used a lot of times and whose users will want to click on the ads. ?

Till next time, ✌️

How to make #money with Google #AdMob ads in #Ionic framework 3 https://t.co/In5UPrLTyn

— Nikola Brežnjak (@HitmanHR) August 16, 2017

Programming

Code Complete 2 – Steve McConnell – Design in Construction

I just love Steve McConnell’s classic book Code Complete 2, and I recommend it to everyone in the Software ‘world’ who’s willing to progress and sharpen his skills.

My notes from Part 1: Laying the Foundation are here.

The second part of the book covers the following chapters:

  • Design in Construction
  • Working Classes
  • High-Quality Routines
  • Defensive Programming
  • The Pseudocode Programming Process

In this post I’ll share my notes from the:

Chapter 5: Design in Construction

The Wicked problem is the one that could be defined only by solving it or solving a part of it.

An example is Tacoma Narrows bridge. Only by building the bridge (solving the problem) could they learn about the additional consideration in the problem that allowed them to build another bridge that still stands.

According to Fred Brook, there are essential and accidental types of problems.

Managing complexity is the true primary technical goal in software design.

Internal design characteristics:

  • minimal complexity
  • high fan-in
  • ease of maintenace
  • low-to-medium fan-out
  • minimal connectedness
  • portability
  • extensibility
  • leanness
  • reusability

A good general rule is that a system-level diagram should be acyclic. In other words, a program shouldn’t contain any circular relationship in which Class A uses Class B, Class B uses Class C, and Class C uses Class A.

Steps in designing with objects

  1. Identify the objects and their attributes
    • Computer programs are usually based on real-world entities
  2. Determine what can be done to each object
    • A variety of operations can be performed on each object
  3. Determine what each object can do to the other objects
    • This step is just what it sounds like. The two generic things can do to each other are containment and inheritance
  4. Determine the parts of each object that will be visible to other objects
    • One of the key design decisions is identifying the parts of an object that should be made public and those that should be kept private
  5. Define each object’s public interface
    • Define the formal, syntactic, programing-language-level interfaces to each object. The data and methods the object exposes to every other object are called “public interface.”

Heuristics in terms of Software’s Primary Technical Imperative: Managing Complexity.

Summary of Design Heuristics

  • Find Real-World Objects
  • Form Consistent Abstractions
  • Encapsulate Implementation Details
  • Inherit When Possible
  • Hide Secrets (Information Hiding)

Information hiding is useful at all levels of design, from the use of named constants instead of literals to the creation of data types, to class design, routine design, and subsystem design.

A good class interface is like the tip of an iceberg, leaving most of the class unexposed

Ask yourself what needs to be hidden in this class?

Loose Coupling describes how tightly a class or routine is related to other classes or routines. The goal is to create classes and routines with small, direct, visible, and flexible relations to other classes and routines.

In Software, make the connections among modules as simple as possible.

Life is one big fat program which has a ton of options, but only one nonoptional parameter

The key note is that Classes and routines are first and foremost intellectual tools for reducing complexity. If they’re not making your job simpler, they’re not doing their jobs.

Design patterns

Patterns provide the cores of ready-made solutions that can be used to solve many of software’s most common problems.

  • Abstract Factory
    • Supports creation of sets of related objects by specifying the kind of set but not the kind of each specific
  • Adapter
    • Converts the interface of a class to a different interface
  • Bridge
    • Builds an interface and an implementation in such a way that either can vary without the other
  • Composite
    • Consists of an object that contains additional objects of its own type so that client code can interact with top-level object and not concern itself with all the detailed
  • Decorator
    • Attaches responsibilities to an object dynamically, without creating specific subclasses for each possible configuration of
  • Facade
    • Provides a consistent interface to code that wouldn’t otherwise offer consistent
  • Factory Method
    • Instantiates classes derived from a specific base class without needing to keep track of the individual derived classes anywhere but the Factory
  • Iterator
    • A server object that provides access to each element in a set sequentially
  • Observer
    • Keeps multiple objects in synch with each other by making a third the object responsible for notifying the set of objects about changes
  • Singleton
    • Provides global access to a class that has one and only one instance
  • Strategy
    • Defines a set of algorithms or behaviors that are dynamically interchangeable with each other
  • TemplateMethod
    • Defines the structure of an algorithm but leaves some of the detailed implementation to subclasses

Cohesion refers to how closely all the routines in a class or all the code in the routine support a central purpose

When in doubt use brute force. ~ Butler Lampson

Understand the problem – devise a plan – carry out a plan, look back to see how you did. ~ Polya George

Design practices

  • Iterate
  • Divide and Conquer
  • Top-down and bottom-up
  • Experimental prototyping
    • You have to be prepared to throw away the code (trick: name the classes -prototype-NameClass )

Put your code in a drawer. Then, come and take it out a week later, and you will criticize the fool who wrote it!

People who preach software design as a disciplined activity spend considerable energy making us all feel guilty. We can never be structured enough or object-oriented enough to achieve nirvana in this lifetime. We all truck around a kind of original sin from having learned Basic at an impressionable age. But my bet is that most of us are better designers than the purists will ever acknowledge. ~ P.J. Plauger

Key note for design is to iterate, iterate, and iterate again and after that, you will be happy with your design.

Conclusion

Hope you liked this post and that you’ve seen that this book really has a lot to offer, so I urge you to get your copy, read it and apply it!

Until next time, take care and keep on improving ?

My #notes from the #book Code Complete 2, Chapter 5 by ever so slightly magnificent Steve McConnell https://t.co/GPV0rq6Upd

— Nikola Brežnjak (@HitmanHR) August 13, 2017

Miscellaneou$

Become a speed demon

Here are my notes from the Udemy course Become a speed demon by Jonathan Levi. This may change by the time you read this post, but the course is now on a sale for $10, so you may wanna check it out if you’re into ‘this kind of things’.

Proper preparation is key to everything.

Specific
Measurable
Actionable
Realistic
Time related

The checklist manifesto book

The priority Star Exercise:

Parkinson’s Law – work expands to fill the time available for its completion

Efficient != Effective

15 minutes to get back in the optimal zone after distraction

MEDITATE!

Batching tasks – answer emails @ specific time

Buddhist wheel of life: career, money, health, friends and family, romance, personal growth, fun, and recreation, physical environment

Some cool tools/tips:

  • Pomodoro
  • Rescue Time
  • Scheduling meetings with an app
  • TextExpander
  • Dvorak keyboard
  • Typing numbers is faster if you actually speak them
  • Make use of Siri (or another equivalent on your phone)
  • QuickSilver app for Mac
  • Better Touch Tool
  • IFTTT
  • Sleep Cycle App
  • Bill Guard
  • Mint.com
  • Have someone do your laundry
  • TaskWonder, Workerly, Fiverr

Decision fatigue leads to ego depletion.

Too many options make us miserable.

Sorry I’m so direct, but I’m sure you’re very busy.

Maker vs. Manager time

Become a #speed demon https://t.co/cAfQ8MYpFm

— Nikola Brežnjak (@HitmanHR) August 8, 2017

Quick tips

How to hide the minimap in Visual Studio Code?

This is a quick tip on how to hide the minimap in Visual Studio Code.

In case you’re wondering why someone would like to do this? The answer is that if you have two files open side by side on a screen that’s not too big then any extra space on the screen will come handy.

Surprisingly, there’s no such option in any of the dropdown menus (like it is in Sublime Text 3 for example), so you’ll first have to go to:

Code -> Preferences -> Settings

Screen Shot 2017-07-23 at 11.48.33

Then, enter the following in your user settings object on the right:

"editor.minimap.enabled": false

minimapVisualStudioCode

You can search for any setting and see its default settings on the left-hand side. If you want to change it, just copy it in the object on the right-hand side, change the value, save, and you’re done. 

Btw, even though I’m a paying user of Sublime Text 3, I must admit I’m liking Visual Studio Code more every day. How’s the situation with you guys? Are you also a long-time ST3 user and have tried VSC? If so, I’d like to hear your thoughts about it…

How to hide the #minimap in Visual Studio #Code? https://t.co/81uHJAlpiT

— Nikola Brežnjak (@HitmanHR) August 6, 2017

Ionic3

How to create a calculator application with Ionic framework 3 by using Ionic Creator for UI

This is the second post in a series of posts which will teach you how to take advantage of your web development knowledge in building hybrid applications for iOS and Android. The first post in this series was all about How to get started with Ionic Framework 3 on Windows and Mac.

This second post explains:

  • How to create a calculator interface mockup
  • How to create a calculator interface prototype without coding by using Ionic Creator
  • How to start the Ionic 3 application based on the created interface
  • Which are the most important folders and files and what is the starting point of the Ionic 3 application
  • How to create the calculator logic

Finished project:

  • clone the code from Github
  • in the project directory execute ionic lab to run the project locally in your browser
  • you can check out the live example of this application or view this gif:

Introduction

Since there are not so many Calculator applications in the App Store, who knows, you just may create a bestseller in this category, if you add a needed tweak or two.

All jokes and hopes aside; this seemed to be decent, but still easy to accomplish task. Let’s start this chapter by creating the interface for our application.

Calculator interface mockup

Before starting any application, we should know what we want (well, at least in general). We should know what problem are we trying to solve with our application and how are we going to solve it. Also, we should have a decent idea of how we would want our application to look like.

The answers to the first two questions would be rather easy; the problem is that we can’t do calculations fast enough in our mind (well, except if you’re Arthur Benjamin) and we need a tool to help us with that. Surely, there are specific calculator devices, but it would be too cumbersome to carry one with us all the time.

Besides, since these days almost everyone has a smartphone, it turns out it would be an awesome idea to make an app for it. Because, as they say:

there’s an app for that

Where that is basically everything these days. If you find that there isn’t an app for some particular problem that you may have, that just may be your lucky break. Who knows, you just may end up having your 5 minutes of fame on the AppStore, until another clone of your app pushes you away.

Anyways, back to our calculator application; we don’t need any fancy options (at least not yet, in this 1.0 version), we’ll just stick with the basic mathematical operations like adding, subtracting, dividing and multiplying.

These basic operations will be our MVP (Minimum Viable Product), as the author Eric Ries explains in his awesome (and highly recommended) book Lean Startup. We can always add features later if it turns out that our idea was good. Or, we can pivot away from it, if it turns out it was not a next best thing after Flappy Bird. That way, we wouldn’t spend too much time and money building the app with a dozen features which, in the end, would not be used at all.

As for the user interface, you can use various tools that help with mocking up your application’s user interface (Balsamiq Mockups, Mockingbird, Mockup Builder). I tend to be old school about it, and I made a little hand drawing of how I imagined the app should look like, and this is what I came up with after few attempts:

Calculator interface prototype

Now that we know what our application needs to do and how it has to look like, let’s start by creating our interface.

We could create our interface by manually coding it in HTML/CSS, but we’re going to show a different approach here – the one which uses Ionic Creator, which is an awesome web application (soon to be a desktop app as well) that lets you drag&drop components that make up the user interface. As such, this is a great tool which helps in quick user interface prototyping.

The best thing is that you can then just download the created HTML/CSS (just recently they’ve added Ionic 3 support) and use it directly in your Ionic application. Of course, some additional changes will be needed later in the HTML and CSS code, but for creating a quick prototype, this will be more than enough.

Worth noting is that there are currently on the market lots of other tools for interface prototyping (InVision, Flinto, Figma 2.0). However, these tools don’t (at least not yet) have a “one-click download and ready for Ionic” option like Ionic Creator does.

Creating calculator interface with Ionic Creator

To use Ionic Creator you have to signup/login on their website. They are currently offering a 14-day trial (no credit card needed to sign up) of Creator Pro which is their best plan and has the following features:

On the initial screen, click the New Project button and fill out project’s name, type and Ionic version:

Please note that Ionic 3 code export is in Alpha mode currently – this will change in the coming months

The main screen of the Ionic Creator application looks like this:

In the upper left-hand side you’ll see the Pages panel, and inside it, you’ll see the Page item. Click on Page, and on the right-hand side change the Title to Calculator. Next, disable the Padding option by switching off the Padding checkbox under the Miscellaneous section on the right-hand side. The way this should look like now is shown on the image below:

First, we need some kind of a “display” which will show the numbers that we’re clicking. Ideally, we would use a <label> component, however, it’s not available in the Ionic Creator as of yet. So, for this, we will use the <input> element, and we can easily adjust this later when we download the generated HTML code.

Ionic Creator works in a drag&drop kind of way, which basically means that you can drag any component from the Components pane on the left-hand side and drop it on the Phone image in the center of the screen.

Since we concluded that we’d use the Input element, just drag&drop it to the Phone.

Select the Input component (by clicking on it in the Pages panel in the upper left corner mentioned before) and:

  • change Placeholder to 0 (zero digit)
  • change Name to display
  • remove the text under Title

The way this should look like now is shown on the image below:

Next, according to our mockup, we should add buttons that would represent the following:

  • digits from 0 to 9
  • adding (+)
  • substracting (–)
  • multiplying (x)
  • dividing (/)
  • modulo (%) – we are, after all, programmers, right? ?‍? ?

Also, we would need an equals button (=), a clear button (C) and a floating point (.) button.

In the first row we need to have three buttons, the ones representing the Clear operation (C), modulo operation (%) and divide operation (/). To accomplish this, we will use a Button component from the Components panel and drag&drop it just below the Input field on the screen. But, before you do that, you have to drag&drop the Container component as we will drop these operation buttons into it.

So, to sum up:
+ first, drag&drop the Container component, and then
+ drag&drop the Button component to the phone image inside the Container component

When done, change the Button’s Width property under the Style section on the right-hand side to Inline and color to Energized. Now, either repeat the process two more times or click on the duplicate icon which appears on the Button component once selected (just left of the x icon). Then change the Text of the buttons to C, % and / respectively. You should see something like this now in your Ionic Creator window:

Don’t worry that this now doesn’t look like in our design; we will deal with this at a later stage.

Those of you familiar with Ionic 1 (also covered in my previous book) know that we had the useful Button Bar component which doesn’t exist in Creator now, but we still have few options.

Now, repeat the process for the second row by first adding another Container component below the previous one and then adding four buttons: 7, 8, 9 and x into it. The additional change on the number buttons is that you need to set their color to Positive (TBH, ‘Positive` is the default color, so you basically won’t have to change anything).

Now you need to repeat the process by adding next three rows. The best thing you can do to speed up the process is to duplicate the whole row by clicking the duplicate icon:

and then change the button text to represent all the missing buttons per rows:

  • buttons representing 4, 5, 6 and a button representing subtraction (–)
  • buttons representing 1, 2, 3 and a button representing addition (+)

Number buttons should have a Positive style, and operation buttons should have an Energized style.

In the last row you should add three buttons (just delete one after you duplicate the whole row of four buttons):

  • one button representing 0, with the Positive style
  • one button representing floating point (.)
  • one button representing the Equals operation (=), with the Assertive style

Your interface should now look like this:

Don’t worry about the slight misalignment or padding; we’ll take care of this in the next chapter when we’ll be polishing our application and preparing it for the App/Play store.

So, this is it, we have our interface ready, and now we can export it by clicking on the Export icon in the header, as shown in the image below:

After this a popup, with the following content, appears:

Click the Download project ZIP button and save it to your computer.

Starting a project with Ionic CLI by using the template made in Ionic Creator

First, unzip the file that you’ve downloaded in the previous step. Then, start a new Ionic app by executing the following command in your Terminal:

ionic start Ionic3_2ndTutorial blank

Now go into the newly created Ionic3_2ndTutorial directory, and overwrite the src folder with the contents from your zip export. You will want to overwrite the app directory, pages directory, and index.html file.

Note: you’re free to name your project any way you want, I chose Ionic3_2ndTutorial in this example, and I used the ‘blank’ template.

Now, let’s see this in action; execute ionic lab and you should get an output like this:

[INFO] Starting app-scripts server: --lab --l --port 8100 --p 8100 --livereload-port 35729 --r 35729 --address 0.0.0.0 -
       Ctrl+C to cancel
[09:39:31]  watch started ... 
[09:39:31]  build dev started ... 
[09:39:31]  clean started ... 
[09:39:31]  clean finished in less than 1 ms 
[09:39:31]  copy started ... 
[09:39:31]  transpile started ... 
[09:39:33]  transpile finished in 1.83 s 
[09:39:33]  preprocess started ... 
[09:39:33]  deeplinks started ... 
[09:39:33]  deeplinks finished in 6 ms 
[09:39:33]  preprocess finished in 7 ms 
[09:39:33]  webpack started ... 
[09:39:33]  copy finished in 1.98 s 
[09:39:38]  webpack finished in 5.41 s 
[09:39:38]  sass started ... 
[09:39:39]  sass finished in 1.02 s 
[09:39:39]  postprocess started ... 
[09:39:39]  postprocess finished in 9 ms 
[09:39:39]  lint started ... 
[09:39:39]  build dev finished in 8.32 s 
[09:39:39]  watch ready in 8.36 s 
[09:39:39]  dev server running: http://localhost:8100/ 

[INFO] Development server running
       Local: http://localhost:8100

[09:39:42]  lint finished in 2.32 s

In the first tutorial we used the ionic serve command which starts up a local web browser and shows how our application would look like. This one is similar but in a way better as it can nicely show us how our app would look like on different platforms:

You can still use the ionic serve command if you like. The live preview is great for rapid development since you get to see changes instantly without needing to reload your browser manually.

If you get an error similar to this:
Error: tsconfig: Cannot read file '/DEV/Ionic3_2ndTutorial/src/tsconfig.json': ENOENT: no such file or directory, open '/DEV/Ionic3_2ndTutorial/src/tsconfig.json'.
then you didn’t run the ionic lab command in the project directory and so you should first cd into that directory (as mentioned in the previous step) and then run the ionic lab command.

Now, let’s go and see what our generated folder structure looks like and what is each folder responsible for.

Ionic application folder structure

If you open up the project in your editor (I’m using Visual Studio Code), you will see something like:

Now we’re going to explain what each of these files and folders represents in Ionic framework 3.

hooks folder

hooks folder contains code for Cordova hooks, which are used to execute some code during the Cordova build process. For example, Ionic uses Cordova’s after_prepare hook to inject platform specific (iOS, Android, Windows Phone) CSS and HTML code.

node_modules folder

node_modules folder contains all the Node modules that Ionic CLI uses in the background like for example babel, browserify, lodash, uglify, webpack to name just a few. There are 550+ tools in that folder ?, and you shouldn’t worry about it at this point at all.

resources folder

resources folder contains two files (icon.png and splash.png) and two folders (android and ios) which contain all the needed icon and splash screen sizes. Ionic has a simple command which creates all the icon and splash screen sizes for you automatically. We will cover that in more detail in the next tutorial.

src folder

src folder is the most important since it contains all the files our application is made of, and we will be spending most of our development time in this folder. This folder contains few files and additional sub folders which we’ll address in more detail in the next section titled Refactoring our application.

www folder

www folder contains the optimized version of our application (minimized, compressed, etc.). In future tutorials, we’ll show how easy it is to just take the contents of this folder and put it on your web server, and you would have the application ready and running. If you take a look at the live example of this project, this is exactly what I did.

.editorconfig file

.editorconfig is a configuration file for Visual Studio Code.

config.xml file

config.xml is a configuration file for the Cordova project (as you may remember from the first tutorial, Ionic is built on top of Cordova). It contains some meta information about the app like permissions and a list of Cordova plugins which are used in the app. To learn more about available settings in the config.xml file, please refer to the official documentation.

ionic.config.json file

ionic.config.json is a configuration file for Ionic, used to store meta information about an Ionic project and the associated Ionic.io cloud account. We’re not going to use Ionic.io cloud account just yet, we’ll show how to use it in the next chapter.

The contents of my ionic.config.json file is as follows:

{
  "name": "Ionic3_2ndTutorial",
  "app_id": "",
  "type": "ionic-angular"
}

It defines the name of the app and its type, along with the app_id in case you’ve created the Cloud account for this project (if you’ve answered Yes to the question when starting the project).

package.json file

package.json is a file used by npm to store versions of the npm packages installed in the current project.

npm (Node.js Package Manager) is a CLI tool which comes with Node.js installation and it’s used for installing other tools like aforementioned Browserify, Babel, etc…

Contents of my package.json file, shown below, is useful as we can see which Cordova plugins and dependencies we have installed on the project, as well as some meta information like name, version and description:

{
  "name": "Ionic3_2ndTutorial",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/compiler-cli": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "4.1.3",
    "@angular/http": "4.1.3",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@ionic-native/core": "3.12.1",
    "@ionic-native/splash-screen": "3.12.1",
    "@ionic-native/status-bar": "3.12.1",
    "@ionic/storage": "2.0.1",
    "ionic-angular": "3.5.3",
    "ionicons": "3.0.0",
    "rxjs": "5.4.0",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.12"
  },
  "devDependencies": {
    "@ionic/app-scripts": "2.0.2",
    "@ionic/cli-plugin-ionic-angular": "1.3.2",
    "typescript": "2.3.4"
  },
  "description": "An Ionic project"
}

package-lock.json file

package-lock.json file is automatically generated for any operation where npm modifies either the node_modules folder or package.json file. It describes the exact folder contents that was generated so that future installs can generate identical folder contents, regardless of intermediate dependency updates. This file is intended to be committed into source repositories so that your teammates (or continuous integration systems, if you have those set up) are guaranteed to install exactly the same dependencies.

.gitignore and README.md file

Both .gitignore and README.md are files related to GitHub.

I’m sure most of the readers know and use GitHub (and consequently Git), but just for brevity, let see how Wikipedia defines GitHub:

GitHub is a Web-based Git repository hosting service, which offers all of the distributed revision control and source code management (SCM) functionality of Git as well as adding its own features. Unlike Git, which is strictly a command-line tool, GitHub provides a Web-based graphical interface and desktop as well as mobile integration. It also provides access control and several collaboration features such as bug tracking, feature requests, task management, and wikis for every project.

So, Git on the other hand is (quoted from the official site):

a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git is easy to learn and has a tiny footprint with lightning fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows.

If you’re not using Git (and Github) in your workflow, I highly encourage you to do so, as it will prove really useful in the long run.

Now that we got the basics out of the way let’s take a look at what the files above represent.

.gitignore is a configuration file for GitHub. Contents of the .gitignore file, shown below, basically instructs Git which folders it shouldn’t track and upload to GitHub.

# Specifies intentionally untracked files to ignore when using Git
# http://git-scm.com/docs/gitignore

*~
*.sw[mnpcod]
*.log
*.tmp
*.tmp.*
log.txt
*.sublime-project
*.sublime-workspace
.vscode/
npm-debug.log*

.idea/
.sass-cache/
.tmp/
.versions/
coverage/
dist/
node_modules/
tmp/
temp/
hooks/
platforms/
plugins/
plugins/android.json
plugins/ios.json
www/
$RECYCLE.BIN/

.DS_Store
Thumbs.db
UserInterfaceState.xcuserstate

README.md is a Markdown file used on GitHub to document the purpose and usage of your project. In general, IMHO, every project should have a decently written README.md file which explains the basic usage of the project along with instructions on how to run it, contribute to it, etc.

tsconfig.json file

tsconfig.json is TypeScript configuration file. We won’t go into the details here, but I encourage you to take a look at the official documentation.

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es5"
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}

tslint.json file

tslint.json is TypeScript Linter configuration file. Linter is a program which checks TypeScript code for readability, maintainability, and functionality errors. For more info, and to learn what the contents of the file shown below represents, please check the official docs.

{
  "rules": {
    "no-duplicate-variable": true,
    "no-unused-variable": [
      true
    ]
  },
  "rulesDirectory": [
    "node_modules/tslint-eslint-rules/dist/rules"
  ]
}

Refactoring our application

As said, we’ll be spending most of our development time in the src folder, and that’s why we mentioned it just briefly in the previous section. We’ll take a full deep dive into it here, by explaining each file (that we’ll change) in detail.

Finally, we’ll add the calculator logic so that our calculator will work as expected.

Generally, putting all the code in one file and mixing logic and presentation (JavaScript and HTML code) is simply a big NO-NO, and often referred to as spaghetti code. You can learn more about refactoring your code from the cult book Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, and others. If you’re searching for a bit lighter introduction to refactoring and good programing practices, in general, I can’t recommend the classic Code Complete 2 by Steve McConnell enough. I’ve read the book way back in 2011, and you can read my notes from the first part of the book here.

^ This was the comment from the first edition of this book (covering Ionic 1). I am happy to report that ever since Ionic has done an awesome job in separating the logic and presentation into components. Mainly this benefit comes from Angular (currently at version 4.x).

index.html file

The starting point of our Ionic application is index.html, whose contents is as follows:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="UTF-8">
  <title>Ionic3Calculator</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="format-detection" content="telephone=no">
  <meta name="msapplication-tap-highlight" content="no">

  <link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
  <link rel="manifest" href="manifest.json">
  <meta name="theme-color" content="#4e8ef7">

  <!-- cordova.js required for cordova apps -->
  <script src="cordova.js"></script>

  <!-- un-comment this code to enable service worker
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.log('Error', err));
    }
  </script>-->

  <link href="build/main.css" rel="stylesheet">

</head>
<body>

  <!-- Ionic's root component and where the app will load -->
  <ion-app></ion-app>

  <!-- The polyfills js is generated during the build process -->
  <script src="build/polyfills.js"></script>

  <!-- The vendor js is generated during the build process
       It contains all of the dependencies in node_modules -->
  <script src="build/vendor.js"></script>

  <!-- The bundle js is generated during the build process -->
  <script src="build/main.js"></script>

</body>
</html>

I’m expecting that you have a decent understanding of HTML, so I won’t explain every HTML tag.

In the index.html file we’re loading in the CSS and JS files from the build folder. The most important tag is <ion-app></ion-app> since this is where we’ll be loading our application.

app folder

The app folder with the src folder is the starting point of every Ionic3 application.

app.components.ts file

Here I won’t go into too much detail (as this post is long enough on its own now ?) but I want to show you where your page is being loaded in. The contents of the file should be as follows:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { CalculatorPage } from '../pages/calculator/calculator';

@Component({
    templateUrl: 'app.html'
})

export class MyApp {
    rootPage: any = CalculatorPage;

    constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
        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();
            splashScreen.hide();
        });
    }
}

The important line here is rootPage: any = CalculatorPage; which sets the root page of your app to the CalculatorPage, which again is imported at the beginning of the file:

import { CalculatorPage } from '../pages/calculator/calculator';.

platform.ready event is triggered after the device (your mobile phone on which the application is started) is all set up and ready to use. This includes plugins which are used in this project. If you would try to check if some plugin is available outside of the ready function callback, you could get wrong results because it is possible that some plugin would not have been set up just yet. You can learn more about Ionic Platform utility methods here.

Important to note are the places in code where and how the same CalculatorPage is injected in the app.module.ts file and added in the @NgModule declarations and entryComponents.

In this app folder, in the file app.scss you could put some style rules that you want to apply globally for your application. We’ll cover styling in the next tutorial where we’ll polish our existing calculator application.

cordova.js, manifest.json and service-worker.json files

We won’t be dealing with these three files in this tutorial. We’ll leave them for another tutorial in which we’ll explain how to create a PWA (Progressive Web App) with Ionic and how to use native plugins (accessing Camera, etc.).

Calculator logic with controllers

Ionic Creator has nicely generated a calculator page for us in the pages folder:

As mentioned before, the organization like this is so much better from what we had before as now we have three files per each component:

  • HTML template file (calculator.html)
  • SASS file (calculator.scss)
  • TypeScript file (calculator.ts)

This way we have the presentation (HTML + CSS) and logic (TS) separated and this is something you should always strive for.

Ionic Creator generated the following code for our calculator.ts file:

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

@Component({
    selector: 'page-calculator',
    templateUrl: 'calculator.html'
})
export class CalculatorPage {
    constructor(public navCtrl: NavController) {

    }
}

This is a bare bones code template where we’re importing the Component and NavController components; then we’re defining our Component decorator selector and templateUrl. Finally, we’re exporting the CalculatorPage class and defining the constructor inside it.

The templateUrl defines the location of the HTML template, and the selector defines the HTML tag (<page-calculator></page-calculator>) that will be used in our template once the app is generated:

Here we’re going to add the small piece of code which will make our app justWork™. Just add this code in the CalculatorPage class:

result = '';

btnClicked(btn) {
    if (btn == 'C') {
        this.result = '';
    }
    else if (btn == '=') {
        this.result = eval(this.result);
    }
    else {
        this.result += btn;
    }
}

In this code, we’re defining a variable result, so that we can show it in our template file (calculator.html).

Next, we defined a new function called btnClicked which accepts one parameter named btn. Inside the function, we’re checking for the passed parameter, and we have three cases based on the value of the parameter that is passed:

  • if the parameter equals C then we’re clearing the result
  • if the parameter equals = then we’re calculating the equation and showing the result
  • in any other case we’re just appending the button’s value to the current equation

Please note that because of brevity we haven’t added any additional checks like if someone accidentally (or intentionally) clicks two times on a button which represents some operation. We will “fix” this in the next chapter when we’ll be polishing the application. Also, you may have read on the Internet that using eval is wrong or just bad. True, it can be bad if used to evaluate some other user input, but in this case, we’ll be fine.

Finishing the calculator template

The only thing which is left for us to do is to add the appropriate function calls on the buttons in the calculator.html template. All that we have to do is add the (click)="btnClicked() function call to each button, and pass in the appropriate parameter. The template that Ionic Creator created for us looks like this:

<ion-header>
    <ion-navbar>
        <ion-title>
            Calculator
        </ion-title>
    </ion-navbar>
</ion-header>

<ion-content id="page1">
    <form id="calculator-form1">
        <ion-item id="calculator-input1">
            <ion-label></ion-label>
            <ion-input type="text" placeholder="0" name="display"></ion-input>
        </ion-item>
    </form>

    <div id="calculator-container3">
        <button id="calculator-button1" ion-button color="energized"> C </button>
        <button id="calculator-button2" ion-button color="energized"> % </button>
        <button id="calculator-button3" ion-button color="energized"> / </button>
    </div>

    <div id="calculator-container6">
        <button id="calculator-button10" ion-button color="positive"> 7 </button>
        <button id="calculator-button11" ion-button color="positive"> 8 </button>
        <button id="calculator-button12" ion-button color="positive"> 9 </button>
        <button id="calculator-button13" ion-button color="energized"> x </button>
    </div>

    <div id="calculator-container7">
        <button id="calculator-button14" ion-button color="positive"> 4 </button>
        <button id="calculator-button15" ion-button color="positive"> 5 </button>
        <button id="calculator-button16" ion-button color="positive"> 6 </button>
        <button id="calculator-button17" ion-button color="energized"> - </button>
    </div>

    <div id="calculator-container8">
        <button id="calculator-button18" ion-button color="positive"> 1 </button>
        <button id="calculator-button19" ion-button color="positive"> 2 </button>
        <button id="calculator-button20" ion-button color="positive"> 3 </button>
        <button id="calculator-button21" ion-button color="energized"> + </button>
    </div>

    <div id="calculator-container9">
        <button id="calculator-button22" ion-button color="positive"> 0 </button>
        <button id="calculator-button23" ion-button color="positive"> , </button>
        <button id="calculator-button25" ion-button color="energized"> = </button>
    </div>
</ion-content>

I have to note that in the current version of Ionic Creator export they still have the old names for colors and we will have to change this. The old Ionic 1 style colors were this:

$light:                           #fff !default;
$stable:                          #f8f8f8 !default;
$positive:                        #387ef5 !default;
$calm:                            #11c1f3 !default;
$balanced:                        #33cd5f !default;
$energized:                       #ffc900 !default;
$assertive:                       #ef473a !default;
$royal:                           #886aea !default;
$dark:                            #444 !default;

The new color names are now these (defined in the src/theme/variables.scss file):

$colors: (
    primary:    #488aff,
    secondary:  #32db64,
    danger:     #f53d3d,
    light:      #f4f4f4,
    dark:       #222,
    energized: #ffc900;
);

In our template, where we have color="positive" we can just delete that as that is now the default color if no color is defined on the button.

So, we won’t change the existing names, as then we would break the code for where this particular variable name is used. We will just add our own class for energized so that the new colors array will look like this:

$colors: (
    primary:    #488aff,
    secondary:  #32db64,
    danger:     #f53d3d,
    light:      #f4f4f4,
    dark:       #222,
    energized: #ffc900
);

Additionally, somewhat a departure from the design, we will add the danger color to the buttons C and =.

This is how the template should look like now:

<ion-header>
    <ion-navbar>
        <ion-title>
            Calculator
        </ion-title>
    </ion-navbar>
</ion-header>

<ion-content id="page1">
    <form id="calculator-form1">
        <ion-item id="calculator-input1">
            <ion-label></ion-label>
            <ion-input type="text" placeholder="0" name="display" [(ngModel)]="result"></ion-input>
        </ion-item>
    </form>

    <div id="calculator-container3">
        <button id="calculator-button1" ion-button color="danger" (click)="btnClicked('C')"> C </button>
        <button id="calculator-button2" ion-button color="energized" (click)="btnClicked('%')"> % </button>
        <button id="calculator-button3" ion-button color="energized" (click)="btnClicked('/')"> / </button>
    </div>

    <div id="calculator-container6">
        <button id="calculator-button10" ion-button (click)="btnClicked('7')"> 7 </button>
        <button id="calculator-button11" ion-button (click)="btnClicked('8')"> 8 </button>
        <button id="calculator-button12" ion-button (click)="btnClicked('9')"> 9 </button>
        <button id="calculator-button13" ion-button color="energized" (click)="btnClicked('*')"> * </button>
    </div>

    <div id="calculator-container7">
        <button id="calculator-button14" ion-button (click)="btnClicked('4')"> 4 </button>
        <button id="calculator-button15" ion-button (click)="btnClicked('5')"> 5 </button>
        <button id="calculator-button16" ion-button (click)="btnClicked('6')"> 6 </button>
        <button id="calculator-button17" ion-button color="energized" (click)="btnClicked('-')"> - </button>
    </div>

    <div id="calculator-container8">
        <button id="calculator-button18" ion-button (click)="btnClicked('1')"> 1 </button>
        <button id="calculator-button19" ion-button (click)="btnClicked('2')"> 2 </button>
        <button id="calculator-button20" ion-button (click)="btnClicked('3')"> 3 </button>
        <button id="calculator-button21" ion-button color="energized" (click)="btnClicked('+')"> + </button>
    </div>

    <div id="calculator-container9">
        <button id="calculator-button22" ion-button (click)="btnClicked('0')"> 0 </button>
        <button id="calculator-button23" ion-button (click)="btnClicked('.')"> . </button>
        <button id="calculator-button25" ion-button color="danger" (click)="btnClicked('=')"> = </button>
    </div>
</ion-content>

As you can see from the code, we’re passing to the function an argument which represents the clicked button.

Also, worth noting is that we used the

[(ngModel)]="result"

on the input element, so that we can access it from the controller through the Angular two-way binding and that we can enter some formula in the input field ourselves as well.

We could have used just the one-way binding like this:

[ngModel]="result"

but if we manually entered something in the input field, it would not ‘propagate’ to our code.

Run the application

Now you can run the application by executing the command

ionic lab

and you should see your awesome calculator open up in your browser:

as noted before, don’t worry this doesn’t look ‘slick’ or that it doesn’t ‘pop’ (or some other nonsense word the ‘knowledgeable’ people use these days), we’ll take care of this in the following tutorial.

The best thing, it should ? also work as expected. So, if you try to enter something like 2+3-10*2 and tap on = you should get the expected -15 (yes, operator precedence is taking place correctly).

We also have the floating point arithmetic like 2.3+3.2 equals 5.5.

As mentioned at the beginning of this chapter, you can take a look at the source code on GitHub, or you can take a look at the live example of this application.

Conclusion

In this chapter, we covered how to create a calculator application step by step. We showed how to create a mockup of our idea; then we showed how to create an interface by using Ionic Creator, and finally how to implement calculator’s logic.

In the next chapter, we’re going to take a look at how to test our application on the real physical devices, and how to use Ionic View App to share our application with other users without going through the app store. Also, we’re going to take a look at how to implement Google Analytics and Google Admob ads, and how to prepare our application for the stores. Additionally, we’ll take a look at how to customize the icons and the application’s splash screen.

Until next time, keep on improving ?

How to create a #calculator application with @Ionicframework 3 by using #Ionic Creator for UI https://t.co/ElzEhU8Jrc

— Nikola Brežnjak (@HitmanHR) August 2, 2017

Programming

Code Complete 2 – Steve McConnell – Part 1: Laying the Foundation

I just love Steve McConnell’s classic book Code Complete 2, and I recommend it to everyone in the Software ‘world’ who’s willing to progress and sharpen his skills.

I read the book way back in 2011, took notes and wrote them down in my notebook, as I usually do:

In this notebook, I have several book notes, and the best of all of them landed on the inner pages of the covers:

Wishful thinking: one day this will be worth ???

Now, I figured I should get these good passages and quotes and my observations out to the blog for easier search in the future.

Too bad the actual books don’t come with a search functionality, right? ? Well, just get a Kindle, right? Honestly, I did and it seems like I still prefer ‘real’ books.

Anyways, in this post we’ll cover the whole Part 1: Laying the Foundation which consists of 4 chapters:

  • Welcome to Software Construction
  • Metaphors for a Richer Understanding of Software Development
  • Measure Twice, Cut Once: Upstream Prerequisites
  • Key Construction Decisions

The post which covers the chapter 5. Design in Construction is here.

So, let’s get to it, shall we?

Chapter 1: Welcome to Software Construction

Software construction is the central activity in software development. Construction is the only activity that’s guaranteed to happen on every project. The main activities in construction are

  • detailed design
  • coding and debugging
  • integration and
  • developer testing (unit testing and integration testing)

The quality of the construction substantially affects the quality of the software.

Chapter 2: Metaphors for a Richer Understanding of Software Development

An algorithm is a set of well-defined instructions for carrying out a particular task. On the other hand, a heuristic is a technique that helps you look for an answer. Its results are subject to change because a heuristic tells you only how to look, not what to find. Metaphors are heuristics, not algorithms. As such, they tend to be a little sloppy.

Treating software construction as similar to building construction suggests that careful preparation is needed and illuminates the difference between large and small projects.

From perspective of planning it’s not the same to build a doghouse or a skyscraper.

Also, a good metaphor for software construction is an oyster forming a pearl. The image is a good way to visualize incremental development or gradual change.

Thinking of software-development practices as tools in an intellectual toolbox suggests further that every programmer has many tools and that no single tool is right for every job. Choosing the right tool for each problem is one key to being an effective programmer.

Chapter 3: Measure Twice, Cut Once: Upstream Prerequisites

Be sure your preparation activities are reducing risks, not increasing them. If you want to develop high-quality software, attention to quality must be part of the software-development process from the beginning to the end. Attention to quality at the beginning has a greater influence on product quality than attention at the end. In general, the principle is to find an error as close as possible to the time at which it was introduced. The longer the defect stays in the software “food chain”, the more damage it causes further down the chain.

The overarching goal of preparing for construction is risk reduction.

Iterative approaches tend to reduce the impact of inadequate upstream work, but they don’t eliminate it. You might choose a more sequential (up-front) approach when:

  • requirements are fairly stable
  • little project risks
  • long-term predictability is important
  • The cost of changing requirements, design, and code downstream is likely to be high

You might choose a more iterative (as you go) approach when:

  • requirements are not well understood
  • the design is complex, challenging, or both
  • the development team is unfamiliar with the applications area
  • the project contains a lot of risks
  • long-term predictability is not important
  • the cost of changing requirements, design, and code downstream is likely to be low

Part of the programming job is to educate bosses and coworkers about the software-development process, including the importance of adequate preparation before programming begins.

Problem-Definition Prerequisite – the penalty for failing to define the problem is that you can waste a lot of time solving the wrong problem. This is a double-barreled penalty because you also don’t solve the right problem.

The 25% change in requirements results in 70-80% of reworking on the project.

Make sure everyone knows the cost of requirements change.

Requirements Prerequisite – requirements describe in detail what a software system is supposed to do, and they are the first step toward a solution. Paying attention to requirements helps to minimize changes to a system after development begins. If you find a coding error during coding, you change a few lines of code and work goes on. If you find a requirements error during coding, you have to alter the design to meet the changed requirement.

Stable requirements are the holy grail of the software development.

Architecture Prerequisite – Architecture is also known as system architecture, high-level design, and top-level design. The architecture should define the major building block in a program. Every feature listed in the requirement should be covered by at least one building block. Building block should have one area of responsibility, and the minimization of the information that blocks have about each other is needed. Architecture should specify major classes that are used.

It’s good to stick to the 80/20 rule, which specifies the 20% of the classes that make 80% of the system’s behavior.

Esential problem with large systems is maintaining their conceptual integrity.

Typical architectural components are:

  • program organization
  • specification of major classes
  • data design
  • business rules
  • user interface design
  • resource management
  • security
  • performance
  • scalability
  • interoperability
  • internationalization/localization (I18N – Internationalization and L10N – localization)
  • error processing.

The architecture should address all requirements without gold-plating (without containing elements that are not required).

I wonder when managers will start to understand that software development is more than just coding.

WISCA – Why isn’t Sam coding anything?
WIMP – Why isn’t Mary programming?

If you can’t explain something to a six-year-old, you really don’t understand it yourself.

The worst thing that can happen to you is to end up maintaining someone’s code who obviously never heard of classes, cause then you will feel like watching a foreign movie with no subtitles.

Only one subsystem/class should access database

The new design has to be easy to change without affecting business rules and program results.

The architecture should clearly describe a strategy for handling changes.

We’ve always done it that way – be wary of that statement! To this, I’d add “Do your best in trying to inform, but if management doesn’t budge, run away as fast as you can”

Bad requirements – if they are found out later, the fixing costs a lot more.

Chapter 4: Key Construction Decisions

Use a language that you’ve used before, and you will become more experienced with it and more productive

C#, C++, Java, Visual Basic – 5 to 15 times more productive than C, Assembly

Developers working in interpreted languages are more productive than the ones using compiled ones.

Most common languages:

  • Ada – named after Ada Lovelace, the first programmer; used in military, space, and avionic systems
  • Assembly language – assembler, low-level language, used for maximizing speed and code size.
  • C – 1970 Bell Labs
  • C++ – 1980 Bjarne Stroustrup
  • C# – 2001 Microsoft Anders Hejlsberg
  • Cobol – Common Business Oriented Language, developed in 1959 – 1961
  • Fortran – first-high level computer language
  • Java – developed by Sun Microsystems; runs on virtual machine
  • JavaScript – primarily used for client side programming (note by me from 2017: not anymore. Node.js made sure of that.)
  • Perl – string-handling language; often used for system administration tasks.
  • PHP – used to access server-side interactive functions and accessing database information. Note from me: everybody seems to hate this language nowadays ?
  • Python – Python is an interpreted, interactive, object-oriented language that runs in numerous environments
  • SQL – declarative language, meaning that it does not define a sequence of operations, but rather the result of some operations.
  • Visual Basic – high-level, object-oriented, visual programming version of Basic developed by Microsoft.

Programmers who program ‘in’ a language limit their thoughts to constructs that the language directly supports. If the language tools are primitive, the programmer’s thoughts will be primitive.

Programmers who program ‘into’ a language first decide what thoughts they want to express, and then they determine how to express those thoughts using the tools provided by their specific language.

Conclusion

Hope you liked this post and that you’ve seen that this book really has a lot to offer, so I urge you to get your copy, read it and apply it!

Until next time, take care and keep on improving ?

My #notes from all-time classic #book Code Complete 2 by Steve McConnell Part 1: Laying the Foundation https://t.co/8jpjxTgMql

— Nikola Brežnjak (@HitmanHR) August 1, 2017

Page 18 of 51« First...10«17181920»304050...Last »

Recent posts

  • When espanso Breaks on Long Replacement Strings (and How to Fix It)
  • 2024 Top Author on dev.to
  • Hara hachi bun me
  • Discipline is also a talent
  • Play for the fun of it

Categories

  • Android (3)
  • Books (114)
    • Programming (22)
  • CodeProject (36)
  • Daily Thoughts (78)
  • Go (3)
  • iOS (5)
  • JavaScript (128)
    • Angular (4)
    • Angular 2 (3)
    • Ionic (61)
    • Ionic2 (2)
    • Ionic3 (8)
    • MEAN (3)
    • NodeJS (27)
    • Phaser (1)
    • React (1)
    • Three.js (1)
    • Vue.js (3)
  • Leadership (1)
  • Meetups (8)
  • Miscellaneou$ (78)
    • Breaking News (8)
    • CodeSchool (2)
    • Hacker Games (3)
    • Pluralsight (7)
    • Projects (2)
    • Sublime Text (2)
  • PHP (6)
  • Quick tips (41)
  • Servers (8)
    • Heroku (1)
    • Linux (3)
  • Stack Overflow (81)
  • Unity3D (9)
  • Windows (8)
    • C# (2)
    • WPF (3)
  • Wordpress (2)

"There's no short-term solution for a long-term result." ~ Greg Plitt

"Everything around you that you call life was made up by people that were no smarter than you." ~ S. Jobs

"Hard work beats talent when talent doesn't work hard." ~ Tim Notke

© since 2016 - Nikola Brežnjak