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
Books

Coaching for performance – Sir John Whitmore

Here are my notes from the book Coaching for performance by Sir John Whitmore.

Coaching focuses on future possibilities, not past mistakes.

Coaching is unlocking peoples potential to maximize their own performance. It is helping them to learn rather than teaching them.

If blame and criticism are a prevalent communication style and this doesn’t change, relationship failure can be predicted with over 90% accuracy.

Of the spoken word: 7% in words, 38% in the way the words were said, 55% facial expression.

I think this person:
– Is a problem
– Has a problem
– Is on a learning journey and is capable, resourceful and full of potential

Intentionality – set a clear intention for a meeting. 2 min before a meeting: “if the meeting would wildly exceed your expectations, what would happen?” No limits!

Questions for building a great team:
– What would the dream or success look for us working together?
– What would the worst case look like
– What’s the best way for us to achieve success or dream
– What do we need to be mindful of to avoid the worst case
– What permissions each of us wants from each other
– What will we do when things get hard?

Open questions:
– What do you want to achieve
– What’s happening at the moment
– How would you like it to be
– What’s stopping you
– What’s helping you
– What problems might there be
– What can you do
– Who can help you
– Where can you find out more
– What will you do

Don’t ask WHY question => ask “what were the reasons” instead

Don’t ask HOW question => ask “what are the steps” instead

Top 10 questions in coaching:
– If I wasn’t here what would you do
– If you knew the answer, what would it be
– What if there were no limits
– What advice would you give to your friend in the same situation
– Imagine having a dialog with the wisest person you know; what would they tell you to do
– What else?
– What would you like to explore next
– I don’t know where to go next, where would you like to go
– What is the real issue
– What is your commitment on a scale from 1 to 10 to doing it. What can you do in doing it

1on1s:
– Goal setting for the sessions (both long and short-term)
– What do you want?
– Reality check to explore the current situation
– Where are you now?
– Options and alternative strategies
– What could you do?
– Will – What is to be done, when, by whom, and a will to do it
– What will you do?

SMART, PURE and CLEAR goals

Having a big dream brings as much work as a small dream.

To set up accountability:
– What will you do
– When
– How will I know

70 learning through experience on the job
20 learning from other people
10 formal learning

Feedback framework:
– What happened
– What have you learned
– How to use this knowledge in the future

Discussion may be facilitated by the team leader but what happens should be decided by team members.

Bonding opportunity by doing something together.

Our true values reside within us and at the deepest level, those values are universal.

Vue.js

Getting started with Vue.js 2 by building a Giphy search application

TL;DR

This tutorial follows the same pattern as this Angular 2 post. You’ll learn how to use Vue CLI to build a Vue.js 2 application for searching Giphy’s gifs by using their API.

The main reason for making this post was to evaluate a bit more lightweight solution than Angular or React.

I’m using Vue.js 2, and I’ll be referring to it as just Vue.js in the rest of this post.

Introduction

Let’s be honest, even those of us that don’t actually hate the JavaScript ecosystem can understand the frustration with the fact that new JS frameworks are popping up all the time.

I stuck to the Angular bandwagon ever since version 1.0. Even though I would recommend starting a new SPA project with it, I must say that my recent research led me to believe that due to Vue’s progressive and flexible nature, it’s a perfect fit for the teams that have to rewrite old codebases one step at a time.

If you want to check out some detailed comparisons between popular frontend frameworks, here are two great posts:

  • Angular vs. React vs. Vue: A 2017 comparison
  • Vue.js vs. React, Angular, AngularJS, Ember, Knockout, Polymer, Riot

General ‘framework war’ kind of questions I tend to answer in the following way:

Please just stop with the analysis paralysis already.

Do your research, pick a framework (any framework for that matter) that the community is using, use it, and see how far it gets you.

All these talks about X being slow or Y being better just make no sense until you try it yourself for your use case and preference. Besides, nowadays the speed will not be a deciding factor among the top JS frameworks.

With all this said, fasten your seatbelts, take a venti (or trenta) sized cup of coffee, and let’s go!

Demo app

As said, we’ll build an application for searching (and showing) gifs from the Giphy website by using their API.

You can fork the complete source code on Github.

Prerequisites

Make sure that you have the following tools installed:

  • Node.js – step by step guide for both Windows and Mac
  • Git – a fun getting started tutorial

Vue CLI

As their README says:

Vue CLI aims to be the standard tooling baseline for the Vue ecosystem. It ensures the various build tools work smoothly together with sensible defaults so you can focus on writing your app instead of spending days wrangling with configurations. At the same time, it still offers the flexibility to tweak the config of each tool without the need for ejecting.

To installing vue-cli, run:

npm install -g @vue/cli

You can confirm that the installation went well if you run:

vue --help

⚠️ Just for reference (in case you follow this tutorial at a later stage and something is not the same as I output it here), my version (vue --version) as of this writing is 2.9.3.

Starting a new app with Vue CLI

We’ll call our app, originally, giphy-search. So, let’s start a new app using vue-cli:

vue init webpack giphy-search

You should get an output similar to this:

# nikola in ~/DEV/Vue [13:37:99]
? Project name giphy-search
? Project description Giphy search app with Vue.js
? Author Nikola Brežnjak <[email protected]> // I welcome spam ;)
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm

   vue-cli · Generated "giphy-search".

# Installing project dependencies ...

npm notice created a lockfile as package-lock.json. You should commit this file.
added 1349 packages in 28.159s

Running eslint --fix to comply with chosen preset rules...
# ========================

> [email protected] lint /Users/nikola/DEV/TeltechRepos/FrontendEvaluation/Vue/giphy-search
> eslint --ext .js,.vue src "--fix"

# Project initialization finished!
# ========================

To get started:

  cd giphy-search
  npm run dev

Documentation can be found at https://vuejs-templates.github.io/webpack

After this command finishes, let’s cd into the project and run it:

cd giphy-search
npm run dev

You should get:

DONE  Compiled successfully in 3745ms

Your application is running here: http://localhost:8080

You should see the following page in your browser if you visit this link: http://localhost:8080.

Folder structure

Now, let’s open this project in the editor of your choice (I’m using Visual Studio Code), and you should see something like this:

As I said, this is an introduction tutorial to get you running fast so I won’t be going into any specific details this time (this is up for some other posts), so here we’ll only focus on the src folder. The contents of that folder should be something like this:

Adding content

Ok, so, let’s add something to our app.

But, where to start?

Well, one of the first things I do when I come to a project for the first time is look at the generated output. Then I try to find the strings corresponding to that output within the source code.

So, if you search for the string Welcome to Your Vue.js App, you’ll see the string is within the HelloWorld.vue file. This file contains the following (... is used for brevity in the listing below):

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      ...
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      ...
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

Without knowing anything about Vue.js, we can see where we would change the Welcome to Your Vue.js App text. So, let’s change that to Welcome to GiphySearch. While you do that, also remove the contents of the style tag.

Adding input and a button

Our basic application should have one input field and one button.

To do this, add the following code to the HelloWorld.vue file:

<input name="search">

<button>Search</button>

Actions

Having a simple search input field and a button doesn’t help much. We want to click the button, and we want to output something to the console just to verify it’s working correctly.

So, this is how we define a function that will handle button click in Vue:

<button @click="performSearch">Search</button>

But, now if open up your DevTools, you’ll see an error like:

webpack-internal:///./node_modules/vue/dist/vue.esm.js:592 [Vue warn]: Property or method "performSearch" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option or for class-based components, by initializing the property. See https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <HelloWorld> at src/components/HelloWorld.vue
       <App> at src/App.vue
         <Root>

That’s because we haven’t defined the performSearch function anywhere.

Let’s do that now. In the HelloWorld.vue file, add the following function definition inside the script tag, methods object property:

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to GiphySearch"
    };
  },
  methods: {
    performSearch: function() {
      console.log("clicked");
    }
  }
};
</script>

With this, we defined the performSearch function, which doesn’t accept any parameters and it does not return anything.

Taking input

What if we would like to print to the console the string that someone typed in the input field?

Well, first we need to add a new attribute to the input field:

<input name="title" v-model="searchTerm">

The v-model is a directive that instructs Vue to bind the input to the new searchTerm variable.

Finally, change the performSearch function to this:

performSearch: function() {
    console.log(this.searchTerm);
}

Giphy search API

Finally, we come to the cool part, and that is to fetch some data from the service and to show it in our app (in our case, we’ll show images).

So, how do we get this API? Well, if you do a simple Google search for giphy api and open the first link you’ll get the documentation for their API.

We need the search API. If you scroll a bit, you’ll find the following link:

http://api.giphy.com/v1/gifs/search?q=funny+cat&api_key=dc6zaTOxFJmzC

Great, now we see what kind of a request we need to create to search Giphy’s gif database for a certain term.

If you open this link in the browser, you’ll see what the service returns. Something like:

In the next section, we’ll cover retrieving this data from within our app.

Vue.js HTTP requests

We have several options for doing HTTP requests in Vue.js, and some may see this flexibility as a pro and some may see it as a con. Either way, for more options, check out this post.

I chose to go with Axios, as it’s a very popular JavaScript library for making HTTP requests. It’s an HTTP client that makes use of the modern Promises API by default (instead of the ~~ugly~~ not so nice JavaScript callbacks) and runs on both the client and the server (i.e. Node.js).

In your Terminal/Command prompt enter the following command to install axios via npm:

npm install axios --save

Import axios in the HelloWorld.vue file just after the script tag:

import axios from "axios";

The performSearch function should now look like this:

var link = "http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=";
var apiLink = link + this.searchTerm;

axios
.get(apiLink)
.then(response => {
    console.log(response);
})
.catch(error => {
    console.log(error);
});

Just for reference, to put it all in one listing, the contents of the HelloWorld.vue file should be:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <input name="title" v-model="searchTerm">

    <button @click="performSearch()">Search</button>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to GiphySearch"
    };
  },
  methods: {
    performSearch: function() {
      console.log(this.searchTerm);

      var link = "http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=";
      var apiLink = link + this.searchTerm;

      axios
        .get(apiLink)
        .then(response => {
          console.log(response.data);
        })
        .catch(error => {
          console.log(error);
        });
    }
  }
};
</script>

Now, if you run the app, enter something in the search box, and click the search button, you’ll see something like this in your console log:

You can see that we’re getting back the response object and that in its data property there are 25 objects, which hold information about the images that we want to show in our app.

And, well, this is all great now, but we don’t want to be logging out our objects to the console, we want to show them in our app.

To show the image, we need to position ourselves on the object images, then original, and finally on the url property.

Also, we don’t want to just show one image but all of the images. We’ll use the v-for directive for that:

<img v-for="g in giphies" :key="g.id" src="{{g.images.original.url}}">

For reference, here’s the full listing of HelloWorld.vue file:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <input name="title" v-model="searchTerm">

    <button @click="performSearch()">Search</button>

    <div>
        <img v-for="g in giphies" :key="g.id" :src="g.images.original.url">
    </div>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to GiphySearch",
      searchTerm: "cat",
      giphies: []
    };
  },
  methods: {
    performSearch: function() {
      console.log(this.searchTerm);

      var link = "http://api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&q=";
      var apiLink = link + this.searchTerm;

      axios
        .get(apiLink)
        .then(response => {
          this.giphies = response.data.data;
        })
        .catch(error => {
          console.log(error);
        });
    }
  }
};
</script>

At this point, if we take a look at the app and search for example for ‘cat coding’ we’ll get this:

Although the result doesn’t look sleek, our code does exactly what it’s supposed to do. If you want it to look nicer, feel free to add more CSS.

Bulma is a cool framework that I used recently in the JWT authentication in an Angular application with a Go backend post.

Conclusion

In this tutorial, you learned how to get started with using Vue.js by building an application for searching Giphy’s gifs by using their API.

Please leave any comments and feedback in the discussion section below!

Thank you for reading!

Getting started with #Vue.js 2 by building a #Giphy search application https://t.co/AV1kjK6C1m

— Nikola Brežnjak (@HitmanHR) March 26, 2018

Programming

Code Complete 2 – Steve McConnell – Table-Driven Methods

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 (Chapters 1 – 4): Laying the Foundation
  • Chapter 5: Design in Construction
  • Chapter 6: Working Classes
  • Chapter 7: High-Quality Routines
  • Chapter 8: Defensive programming
  • Chapter 9: Pseudocode Programming Process
  • Chapter 10: General Issues in Using Variables
  • Chapter 11: General Issues in Using Variables
  • Chapter 12: Fundemental Data Types
  • Chapter 13: Unusual Data Types
  • Chapter 15: Using Conditionals
  • Chapter 16: Controlling Loops
  • Chapter 17: Unusual Control Structures

Table-driven code can be simpler than complicated logic using ifs. Suppose you wanted to classify characters into letters, punctuation marks, and digits; you might use a logic like this one (Java):

if ( ( ( 'a' <= inputChar ) && (inputChar <= 'z' ) )  || ( ( 'A' <= inputChar ) && (inputChar <= 'Z' ) ) ) {
    charType = CharacterType.Letter;
}
else if ( ( inputChar == ' ' ) || ( inputChar == ',' ) ||( inputChar == '.' ) || ( inputChar == '!' ) || 
    ( inputChar == '(' ) || ( inputChar == ')' ) || 
    ( inputChar == ':' ) || ( inputChar == ';' ) ||
    ( inputChar == '?' ) || ( inputChar == '-' ) ) {

    charType = CharacterType.Punctuation;
} else if ( ( '0' <= inputChar ) && ( inputChar <= '9' ) ) {
    charType = CharacterType.Digit;
}

Two Issues in Using Table-Driven Methods:

  • how to look up entries in the table
  • what to store in the table
    • the result of table lookup can be data, but also an action. In such case, you can store a code that describes the action, or in some languages, you can store a reference to the routine that implements the action. In either of these cases, tables become more complicated.

How to look up entries in the table

You can use some data to access a table directly. If you need to classify the data by month, for example, you can use an array with indexes 1 through 12.

Other data is too awkward to be used to look up a table entry directly. If you need to classify data by Social Security Number, for example, you can’t use the Social Security Number to key into the table directly unless you can afford to store 999-99-9999 entries in your table. You’re forced to use a more complicated approach. Here’s a list of ways to look up an entry in a table:

  • Direct access
  • Indexed access
  • Stair-step access

Direct Access Tables

Suppose you need to determine the number of days per month (forgetting about leap year, for the sake of argument). A clumsy way to do it, of course, is to write a large if statement:

if ( month == 1 ) {
    days = 31;
} else if ( month == 2 ) {
    days = 28;
}
// ...for all 12 months, you get the point
else if ( month == 12 ) {
    days = 31;
}

An easier and more modifiable way to perform the same function is to put the data in a table:

int daysPerMonth [12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Now, instead of using the long if statement, you can just use simple array access to find out the number of days in a month:

days = daysPerMonth[ month - 1 ];

Indexed access Tables

Sometimes a simple mathematical transformation isn’t powerful enough to make the jump from data like Age to a table key.

Suppose you run a warehouse and have an inventory of about 100 items. Suppose further that each item has a four-digit part number that ranges from 0000 through 9999.

First, if each of the entries in the main lookup table is large, it takes a lot less space to create an index array with a lot of wasted space than it does to create a main lookup table with a lot of wasted space.

For example, suppose that the main table takes 100 bytes per entry and that the index array takes 2 bytes per entry. Suppose that the main table has 100 entries and that the data used to access it has 10,000 possible values.

In such a case, the choice is between having an index with 10,000 entries or the main data member with 10,000 entries. If you use an index, your total memory use is 30,000 bytes. If you forgo the index structure and waste space in the main table, your total memory use is 1,000,000 bytes.

That means you waste 97% less memory with indexed access tables.

Stair-Step Access Tables

Another kind of table access is the stair-step method. This access method isn’t as direct as an index structure, but it doesn’t waste as much data space.

The general idea of stair-step structures is that entries in a table are valid for ranges of data rather than for distinct data points.

For example, if you’re writing a grading program, here’s a range of grades you might have to program:

> 90.0% A
< 90.0% B
< 75.0% C
< 65.0% D
< 50.0% F

This is an ugly range for a table lookup because you can’t use a simple data-transformation function to key into the letters A through F. An index scheme would be awkward because the numbers are floating points. You might consider converting the floating-point numbers to integers, and in this case, that would be a valid design option, but for the sake of illustration, this example will stick with floating point.

Here’s the code in Visual Basic that assigns grades to a group of students based on this example.

' set up data for grading table
Dim rangeLimit() As Double = { 50.0, 65.0, 75.0, 90.0, 100.0 }
Dim grade() As String = { "F", "D", "C", "B", "A"}
maxGradeLevel = grade.Length - 1
...
' assign a grade to a student based on the student's score
gradeLevel = 0
studentGrade = "A"
while ( ( studentGrade = "A" ) and ( gradeLevel < maxGradeLevel) ) 
    If ( studentScore < rangeLimit( gradeLevel ) ) Then
        studentGrade = grade( gradeLevel )
    End If
    gradeLevel = gradelevel + 1
wend

Although this is a simple example, you can easily generalize it to handle multiple students, multiple grading schemes, and changes in the grading scheme.

The advantage of this approach over other table-driven methods is that it works well with irregular data. The grading example is simple in that although grades are assigned at irregular intervals, the numbers are “round,” ending with 5s and 0s. The stair-step is equally well suited to data that doesn’t end neatly with 5s and 0s. You can use the stair-step approach in statistics work for probability distributions with numbers like this:

Probability Insurance Claim Amount
0.456935 $0.00
0.546654 $254.32
0.627782 $514.77
0.771234 $717.82

Ugly numbers like these defy any attempt to come up with a function to neatly transform them into table keys. The stair-step approach is the answer.

⚠️ Tables can provide an alternative to complicated logic, so ask yourself whether you could simplify by using a lookup table.

Programming

Code Complete 2 – Steve McConnell – Unusual Control Structures

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 (Chapters 1 – 4): Laying the Foundation
  • Chapter 5: Design in Construction
  • Chapter 6: Working Classes
  • Chapter 7: High-Quality Routines
  • Chapter 8: Defensive programming
  • Chapter 9: Pseudocode Programming Process
  • Chapter 10: General Issues in Using Variables
  • Chapter 11: General Issues in Using Variables
  • Chapter 12: Fundemental Data Types
  • Chapter 13: Unusual Data Types
  • Chapter 15: Using Conditionals
  • Chapter 16: Controlling Loops

Recursion

For a small group of problems, recursion can produce simple, elegant solutions. For a slightly larger group of problems, it can produce simple, elegant, hard-to-understand solutions. ?

Java Example:

void QuickSort( int firstIndex, int lastIndex, String [] names ) {
    if ( lastIndex > firstIndex ) {
        int midPoint =  Partition( firstIndex, lastIndex, names );
        QuickSort( firstIndex, midPoint-1, names );
        QuickSort( midPoint+1, lastIndex, names );            
    }
}

In this case, the sorting algorithm chops an array in two and then calls itself to sort each half of the array. When it calls itself with a subarray that’s too small to sort-such as ( lastIndex <= firstIndex ) – it stops calling itself.

Tips for Using Recursion

  • Make sure the recursion stops – Check the routine to make sure that it includes a nonrecursive path.
  • Limit recursion to one routine – Cyclic recursion (A calls B calls C calls A) is dangerous because it’s hard to detect.
  • Keep an eye on the stack – With recursion, you have no guarantees about how much stack space your program uses. To prevent stack overflow, you can use safety counter and set the limit low enough or allocate objects on the heap using new.
  • Don’t use recursion for factorials or Fibonacci numbers – You should consider alternatives to recursion before using it. You can do anything with stacks and iteration that you can do with recursion. Sometimes one approach works better, sometimes the other does. Consider both before you choose either one.

goto

You might think the debate related to gotos is extinct, but a quick trip through modern source-code repositories like SourceForge.net shows that the goto is still alive and well and living deep in your company’s server.

The Argument Against gotos

The general argument against gotos is that code without them is higher-quality code
+ Dijkstra observed that the quality of the code was inversely proportional to the number of gotos the programmer used
+ Code containing gotos is hard to format
+ Use of gotos defeats compiler optimizations
+ The use of gotos leads to the violation of the principle that code should flow strictly from top to bottom

The Arguments for gotos

The argument for the goto is characterized by advocacy of its careful use in specific circumstances rather than its indiscriminate use.

A well-placed goto can eliminate the need for duplicate code. Duplicate code leads to problems if the two sets of code are modified differently. Duplicate code increases the size of the source and executable files. The bad effects of the goto are outweighed in such a case by the risks of duplicate code.

Good programming doesn’t mean eliminating gotos. Methodical decomposition, refinement, and selection of control structures automatically lead to goto-free programs in most cases. Achieving goto-less code is not the aim but the outcome, and putting the focus on avoiding gotos isn’t helpful.

Summary of Guidelines for Using gotos

Use of gotos is a matter of religion. My dogma is that in modern languages, you can easily replace nine out of ten gotos with equivalent sequential constructs.

  • Use gotos to emulate structured control constructs in languages that don’t support them directly. When you do, emulate them exactly. Don’t abuse the extra flexibility the goto gives you.
  • If goto improve efficiency, document the efficiency improvement so that goto-less evangelists won’t remove it.
  • Limit yourself to one goto label per routine
  • Limit yourself to gotos that go forward, not backward
  • Make sure all gotos labels are used.
  • Make sure a goto doesn’t create unreachable code.

https://t.co/AGH65l2L9F

— Nikola Brežnjak (@HitmanHR) March 12, 2018

Programming

Code Complete 2 – Steve McConnell – Controlling Loops

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 (Chapters 1 – 4): Laying the Foundation
  • Chapter 5: Design in Construction
  • Chapter 6: Working Classes
  • Chapter 7: High-Quality Routines
  • Chapter 8: Defensive programming
  • Chapter 9: Pseudocode Programming Process
  • Chapter 10: General Issues in Using Variables
  • Chapter 11: General Issues in Using Variables
  • Chapter 12: Fundemental Data Types
  • Chapter 13: Unusual Data Types
  • Chapter 15: Using Conditionals

“Loop” is a structure that causes a program to repeatedly execute a block of code. Common loop types are for, while, and do-while.

When to use the while loop

If you don’t know ahead of time exactly how many times you’ll want the loop to iterate, use the while loop. Contrary to what some novices think, the test for the loop exit is performed only once each time through the loop, and the main issue concerning while loop is deciding whether to test at the beginning or the end of the loop.

  • while – loop tests condition at the beginning
  • do-while – tests condition at the end, which means that the body of the loop gets executed at least once.
  • loop-with-exit – structure more closely models human thinking. This is the loop in which the exit condition appears in the middle of the loop rather than at the beginning or the end.

When to use the for loop

A for loop is a good choice when you need a loop that executes a specified number of times. If you have a condition under which execution has to jump out of a loop, use a while loop instead.

When to use the foreach loop

It is useful for performing an operation on each member of an array or some other container. It has an advantage of eliminating loop-housekeeping arithmetic and therefore eliminating any chance of errors in the loop-housekeeping arithmetic.

Controlling the loop

You can use two practices. First, minimize the number of factors that affect the loop. Simplify! Simplify! Simplify! Second, treat the inside of the loop as if it were a routine-keep as much control as possible outside the loop.

Entering the loop

  • Enter the loop from one location only
  • Put initialization code directly before the loop – Principle of Proximity advocates putting related statements together.
  • Use while ( true ) for infinite loops – that’s considered a standard way of writing an infinite loop in C++, Java, Visual Basic, and other languages. for(;;) is an accepted alternative.

Processing the middle of the loop

  • Use { and } to enclose the statements in a loop – Use brackets every time. They don’t cost anything in speed or space at runtime, they help readability, and they help prevent errors as the code is modified.
  • Avoid empty loops – In C++ and Java, it’s possible to create an empty loop, one in which the work the loop is doing is coded on the same line as the test that checks whether the work is finished. Here’s an example:
    while( (inputChar = dataFile.GetChar() ) != CharType_Eof ) {
        ;
    }
    

    The loop would be much clearer if it were recoded so that the work it does is evident to the reader:

    do {
        inputChar = dataFile.GetChar();
    } while ( inputChar != CharType_Eof );
    

The new code takes up three full lines rather than that of one line, which is appropriate since it does the work of three lines rather than that of one line.
+ Keep loop-housekeeping chores at either the beginning or the end of the loop – As a general rule, the variables you initialize before the loop are the variables you’ll manipulate in the housekeeping part of the loop.

Exiting the loop

  • Assure that the loop ends
  • Don’t monkey with the loop index of a for loop to make the loop terminate
  • Avoid code that depends on the loop index’s final value

Exiting loops early

The break statement causes a loop to terminate through the normal exit channel; the program resumes execution at the first statement following the loop.

continue causes the program to skip the loop body and continue executing at the beginning of the next iteration of the loop.

Inefficient programmers tend to experiment randomly until they find a combination that seems to work. If a loop isn’t working the way it’s supposed to; the inefficient programmer changes the < sign to a <= sign. If that fails, the inefficient programmer changes the loop index by adding or subtracting 1. Eventually, the programmer using this approach might stumble onto the right combination or simply replace the original error with a more subtle one. Even if this random process results in a correct program, it doesn’t result in the programmer’s knowing why the program is correct.

How long should a loop be?

Make your loops short enough to view all at once. Experts have suggested a loop-length limit of one page (about 50 lines of code). When you begin to appreciate the principle of writing simple code, however, you’ll rarely write loops longer than 15 or 20 lines.

Creating loops easily – from the inside out

If you sometimes have trouble coding a complex loop, which most programmers do, you can use a simple technique to get it right the first time.

Here’s the general process:
+ Start with one case.
+ Code that case with literals.
+ Then indent it, put a loop around it, and replace the literals with loop indexes or computed expressions.
+ Put another loop around that, if necessary, and replace more literals.
+ Continue the process as long as you have to
+ When you finish, add all the necessary initializations.

Since you start at the simple case and work outward to generalize it, you might think of this as coding from the inside out.

Android

How to make a native Android app that can block phone calls

TL;DR

In this post, I’ll show you step by step how to make a native Android app that can block certain numbers from calling you.

The source code is on Github.

I hope that my step by step guide that I’m going to show you here will help you and save you from doing additional research.

Of course, since I’m not a native Android developer in my day to day job, I’m doing it also for the fact that it will serve me as a good reminder for when I need to deal with a similar situation again. Shout out to the rest of you #jackOfAllTrades out there ?

Also, given the statement above; I would appreciate any feedback regarding this code. ?

!TL;DR

I’ve spent a lot of time going through StackOverflow and blog posts in search of this solution. Of all of those, these were helpful:

  • How to detect incoming calls on an Android device?
  • Can’t answer incoming call in android marshmallow 6.0
  • Android permission doesn’t work even if I have declared it
  • End incoming call programmatically
  • Is the phone ringing

But sadly, none of them was straightforward, beginner kind of tutorial. So, after a lot of additional research, I made it work, and here’s my best attempt at explaining how.

As a sidenote: while testing this, the discovery of how to simulate an incoming call or SMS to an emulator in Android Studio was also very helpful.

Starting a new project

In Android Studio go to File->New->New Project, give it a name and a location and click Next:

Leave the default option for minimum API level:

Select an Empty Activity template:

Leave the name of the activity as is:

AndroidManifest.xml

Set the permissions (two uses-permission tags) and the receiver tags in AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.nikola.callblockingtestdemo">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver  android:name=".IncomingCallReceiver" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

With the READ_PHONE_STATE permission we get this (as defined in official docs):

Allows read-only access to phone state, including the phone number of the device, current cellular network information, the status of any ongoing calls, and a list of any PhoneAccounts registered on the device.

With the CALL_PHONE permission we get this (as defined in official docs):

Allows an application to initiate a phone call without going through the Dialer user interface for the user to confirm the call.

⚠️ I found that even though not stated here, I need this permission so that I can end the call programmatically.

The receiver tag is used to define a class that will handle the broadcast action of android.intent.action.PHONE_STATE. Android OS will broadcast this action when, as the name implies, the state of the phone call changes (we get a call, decline a call, are on the call, etc.).

IncomingCallReceiver.java

Create a new class (File->New->Java Class), call it IncomingCallReceiver and paste this code in (note: your package name will be different than mine!):

package com.example.nikola.callblockingtestdemo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;

public class IncomingCallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        ITelephony telephonyService;
        try {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){
                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                try {
                    Method m = tm.getClass().getDeclaredMethod("getITelephony");

                    m.setAccessible(true);
                    telephonyService = (ITelephony) m.invoke(tm);

                    if ((number != null)) {
                        telephonyService.endCall();
                        Toast.makeText(context, "Ending the call from: " + number, Toast.LENGTH_SHORT).show();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

                Toast.makeText(context, "Ring " + number, Toast.LENGTH_SHORT).show();

            }
            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                Toast.makeText(context, "Answered " + number, Toast.LENGTH_SHORT).show();
            }
            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)){
                Toast.makeText(context, "Idle "+ number, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

In Android, if we want to ‘get’ the data from the BroadcastReceiver, we need to inherit the BroadcastReceiver class, and we need to override the onReceive method. In this method, we’re using the TelephonyManager to get the state of the call, and we’re using the ITelephony interface to end the call.

To be honest, this is where it gets a bit ‘weird’, as to get this ITelephony interface, you need to create the ITelephony interface.

ITelephony.java

To do that, create a new class (File->New->Java Class), call it ITelephony and paste this code in (note: overwrite everything with the below content; yes, even the weird package name):

package com.android.internal.telephony;

public interface ITelephony {
    boolean endCall();
    void answerRingingCall();
    void silenceRinger();
}

Android Studio will complain about package com.android.internal.telephony; (red squiggly dots under this package name), but that’s how it has to be set for this to work. I didn’t find the exact explanation why this has to be included, so if you know, please share it in the comments.

Requesting permissions at runtime

This was one thing that was hindering my success in getting this to work!

Namely, after Android 6.0+, even if you have permissions set in the AndroidManifest.xml file, you still have to explicitly ask the user for them if they fall under the category of dangerous permissions. This is the list of such permissions:

  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION
  • ADD_VOICEMAIL
  • BODY_SENSORS
  • CALL_PHONE
  • CAMERA
  • GET_ACCOUNTS
  • PROCESS_OUTGOING_CALLS
  • READ_CALENDAR
  • READ_CALL_LOG
  • READ_CELL_BROADCASTS
  • READ_CONTACTS
  • READ_EXTERNAL_STORAGE
  • READ_PHONE_STATE
  • READ_SMS
  • RECEIVE_MMS
  • RECEIVE_SMS
  • RECEIVE_WAP_PUSH
  • RECORD_AUDIO
  • SEND_SMS
  • USE_SIP
  • WRITE_CALENDAR
  • WRITE_CALL_LOG
  • WRITE_CONTACTS
  • WRITE_EXTERNAL_STORAGE

To ask for such permissions here’s the code you can use (I used it in MainActivity.java in the onCreate method):

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED || checkSelfPermission(Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED) {
        String[] permissions = {Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE};
        requestPermissions(permissions, PERMISSION_REQUEST_READ_PHONE_STATE);
    }
}

The PERMISSION_REQUEST_READ_PHONE_STATE variable is used to determine which permission was asked for in the onRequestPermissionsResult method. Of course, if you don’t need to execute any logic depending on whether or not the user approved the permission, you can leave out this method:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_READ_PHONE_STATE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Permission granted: " + PERMISSION_REQUEST_READ_PHONE_STATE, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Permission NOT granted: " + PERMISSION_REQUEST_READ_PHONE_STATE, Toast.LENGTH_SHORT).show();
            }

            return;
        }
    }
}

App in action

This is how the app looks like in action, tested on the emulator and call triggered by using Android Device Monitor in Android Studio:

Conclusion

In this post, I showed you how to make a native Android app that can block certain numbers from calling you. I pointed out the blocker that I was facing, and I’m still searching a solution to hide a native incoming call popup that still sometimes shows up for a brief second before the call gets rejected.

So, if you have any ideas, I’m open to suggestions ?

How to make a #native #Android app that can #block phone #calls https://t.co/NMYvOFlPO8

— Nikola Brežnjak (@HitmanHR) February 22, 2018

Android

How to simulate an incoming call or SMS to an emulator in Android Studio

In this quick tip, I’ll show you how easy it is to simulate an incoming call or SMS to an emulator in Android Studio.

TL;DR

In Android Studio, go to Tools->Android->Android Device Monitor

Select the Emulator on the left (you have to run it first – do that through Tools->Android->AVD Manager), then the Emulator Control tab, insert the number, select Voice or SMS and click the Call or Send button:

See both of these functions in action:

Conclusion

In this short tip, I showed you how easy it is to simulate an incoming call or SMS to an emulator in Android Studio.

Android Device Monitor allows you to set other stuff as well, like for example the current location, Network preferences (to test your app in not so ideal connectivity situations), etc.

Hope this helps ?

How to simulate an incoming call or SMS to an emulator in #Android Studio https://t.co/Ou9vRRV7RW

— Nikola Brežnjak (@HitmanHR) February 21, 2018

Projects

DevThink podcast

I’m super happy to announce that my friend (and coworker) Shawn Milochik and I started our very own podcast called DevThink.

In the DevThink podcast we discuss ideas and practices that worked for us in our software development journey so far. We’re also discussing the topics that we’re currently exploring and learning about.

Currently, we published two shows:

  • Is It Worth To Build A Profile On StackOverflow?
  • Dvorak #1 – Impressions After Using It for 2 Weeks

But, we’ve already recorded 8 additional shows that we’ll be publishing one per week.

Of course, feedback is greatly appreciated (be it good or bad)… We’re also open to suggestions for what you’d like to hear us discuss ?

Super happy to announce the DevThink podcast, brought to you by @ShawnMilo and yours truly https://t.co/VwgtRUdXkj

— Nikola Brežnjak (@HitmanHR) February 19, 2018

Angular 2, Go

JWT authentication in an Angular application with a Go backend

TL;DR

In this tutorial, I’m going to show you how to build a simple web app that handles authentication using JWT. The frontend will be written in Angular 5, and the backend will be in Go. I’ll cover some theory concepts along the way as well.

You can check out the final source code on Github.

JWT

JWT stands for JSON Web Token, and it is an encoded string that, for example, looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==.mKIuU0V0Bo99JU5XbeMe6g-Hrd3ZxJRlmdHFrEkz0Wk

If you split this string by ., you’ll get three separate strings:

  • header – contains encoded information about the token
  • payload – contains encoded data that is being transmitted between two parties
  • verification signature – used to verify that the data has not been changed

The official website says this about JWTs:

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

If you’re like

then I don’t blame you. So let’s define this in a bit more detail.

JSON Web Tokens are a way to communicate information between two parties securely. A claim is some data that is sent along with the token, like user_id.

Secure communication in this context refers to the fact that we can be certain that the information has not been tampered with, but it does not mean that it is hidden from a potential attacker. Actually, a potential attacker could read what is in JWT (so please don’t send any passwords as claims), but he wouldn’t be able to modify it and send it back in that form.

Based on the premise that a JWT can’t be tampered with, it is very useful for authentication. We can give a user a JWT that contains their userid, which can be stored locally and used to verify that requests are coming from an authenticated user.

JWTs are short, so you can easily send them as a POST parameter, HTTP header, or add it as a query string to a URL. You can store them in local storage and then send them with every request to the server, making sure the user is authorized.

It seems that a lot of people like and use them. However, I must note that a lot of security researchers frown upon this practice.

Learn by doing

It’s not necessary to know the intricate details of how JWTs work, to be able to use them, but it can sometimes give you this great feeling of awesomeness when you go an extra mile.

So, with that spirit in mind, we’re going to create our own JSON Web Token now ?

Payload

For example, say that I want to send the following data securely to someone:

{
    "user_id": "a1b2c3",
    "username": "nikola"
}

This is my payload. To add it to our JWT, we first need to base64 encode it. You can do this easily with JavaScript inside your browser’s developer tools (Console window) by using the btoa function:

btoa(JSON.stringify({
    "user_id": "a1b2c3",
    "username": "nikola"
}));

Or, with the ever so slightly popular Go, you would do it like this:

package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    data := `{"user_id":"a1b2c3","username":"nikola"}`
    uEnc := base64.URLEncoding.EncodeToString([]byte(data))
    fmt.Println(uEnc)
}

which then gives you:
eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==

⚠️ In the JavaScript example we had to use the JSON.stringify function first, as otherwise the resulting decoded string would just be [object Object].

We can decode the base64 encoded string by using the atob function in JavaScript:

atob('eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==')

or in Go:

uDec, _ := base64.URLEncoding.DecodeString("eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==")

The result, in both cases, is {"user_id":"a1b2c3","username":"nikola"}

Header

Next, we need to encode the header:

{
    "alg": "HS256",
    "typ": "JWT"
}

In JWT, the header actually comes before the payload. In the header, we are specifying that we created a JWT and that we used a certain hashing algorithm HS256. This particular algorithm will allow us to use a secret password. You could use the RSA SHA256 algorithm to use a private & public key pair instead. Here’s a good tutorial on the different hashing algorithms used in JWTs.

The header, base64 encoded, looks like this: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

Verification signature

As the last step, we need to create the verification signature. We do this by joining the encoded header and payload string, separating them with .. After that, we need to apply the HS256 algorithm along with the secret password that is only known to the sender.

Our encoded header and payload look like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==

We’re going to use 42isTheAnswer as our password.

We don’t have this hashing function available in the browser, so we need to use Node to do it. First, install base64url by running: npm install base64url. If you’re new to Node, I recommend this tutorial.

Create a new JavaScript file with the following content:

var base64url = require('base64url');

var crypto    = require('crypto');
var message     = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==';
var key       = '42isTheAnswer';
var algorithm = 'sha256';
var hash, hmac;

hmac = crypto.createHmac(algorithm, key);
hmac.setEncoding('base64');
hmac.write(message);
hmac.end();
hash = hmac.read();

var final = base64url.fromBase64(hash);
console.log(final);

Or, in Go, you would use:

package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
)

func main() {
    message := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ=="
    sKey := "42isTheAnswer"

    key := []byte(sKey)
    h := hmac.New(sha256.New, key)
    h.Write([]byte(message))
    b := base64.URLEncoding.EncodeToString(h.Sum(nil))
    fmt.Println(string(a))
}

After you execute any of the scripts above, you should get this string:

mKIuU0V0Bo99JU5XbeMe6g-Hrd3ZxJRlmdHFrEkz0Wk

Now we add this string to the token from before (also separated by .) and we get:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYTFiMmMzIiwidXNlcm5hbWUiOiJuaWtvbGEifQ==.mKIuU0V0Bo99JU5XbeMe6g-Hrd3ZxJRlmdHFrEkz0Wk

We can test this JWT on jwt.io:

Security

Our payload and header were just base64 encoded, which can just as easily be base64 decoded. So, how exactly is this secure then?

The important point is that it can’t be changed, since the verification signature is built using the header and the payload data, if either of those change, we won’t be able to verify the signature – so if somebody tampers with the JWT, we will know.

Since the payload data has been changed, the verification signature will no longer match, and there’s no way to forge the signature unless you know the secret that was used to hash it. When this JWT hits the server, it will know that it has been tampered with.

General remarks

If JWTs are used for Authentication, they will contain at least a user ID and an expiration timestamp.
This type of token is known as a Bearer Token. It identifies the user that owns it and defines a user session.

A Bearer Token is a signed temporary replacement for the username/password combination. The very first step for implementing JWT-based authentication is to issue a Bearer Token and give it to the user through the process of logging in.

The key property of JWTs is that to confirm if they are valid we only need to look at the token itself.

Demo apps

We’re going to build a simple full-stack app that will have a:

  • landing page
  • login page
  • members page
  • backend for authentication

Here’s how the authentication with JWTs works:

  • user submits the username and password to the server via the login page
  • server validates the sent data and creates a JWT token with a payload containing the user’s id and an expiration timestamp
  • server signs the Header and Payload with a secret password and sends it back to the user’s browser
  • browser takes the signed JWT and starts sending it with each HTTP request back to the server
  • signed JWT acts as a temporary user credential, that replaces the permanent credential (username and password)

Here’s what the server does upon receiving the JWT token:

  • the server checks the JWT signature and confirms that it’s valid
  • the Payload identifies a particular user via a user id
  • only the server has the secret password, and the server only gives out tokens to users that submit the correct password. Therefore, the server can be certain that this token was indeed given to this particular user by the server
  • the server proceeds with processing the HTTP request with this user’s credentials

Angular CLI with Bulma

Angular CLI is an awesome tool for Angular, and Bulma is a simple CSS framework that’s just a pure joy to work with.

Let’s start by generating a new project with Angular CLI (install it, in case you don’t have it already):

ng new jwt-auth

After this process is finished, run ng serve inside the jwt-auth folder, and you’ll have an app running at http://localhost:4200/:

Adding Bulma

Add this in the index.html file:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">
  <script defer src="https://use.fontawesome.com/releases/v5.0.0/js/all.js"></script>

Update app.component.html to:

<nav class="navbar">
  <div class="container">
    <div class="navbar-brand">
      <a class="navbar-item">
        JWT Angular Login
      </a>
    </div>

    <div id="navbarMenuHeroA" class="navbar-menu">
      <div class="navbar-end">
        <a class="navbar-item">
          Home
        </a>
        <a class="navbar-item">
          Login
        </a>
        <a class="navbar-item">
          Members
        </a>
        <a class="navbar-item">
          Logout
        </a>
      </div>
    </div>
  </div>
</nav>

<router-outlet></router-outlet>

<footer class="footer">
  <div class="container has-text-centered">
    <div class="content">
      From Croatia with ❤️
    </div>
  </div>
</footer>

If you take a look at the page now, you’ll see:

So, we have a header with links and a footer with simple text.

The <router-outlet></router-outlet> element will be used to serve other pages.

Now, let’s create three new components using Angular CLI:

ng g component home
ng g component login
ng g component members

One reason why Angular CLI is useful is that by generating the component, it creates 3 files for us and imports the component in the app.module.ts file:

create src/app/members/members.component.css (0 bytes)
create src/app/members/members.component.html (26 bytes)
create src/app/members/members.component.spec.ts (635 bytes)
create src/app/members/members.component.ts (273 bytes)
update src/app/app.module.ts (1124 bytes)

Now, let’s wire up the routes in app.module.ts:

const routes = [
    { path: 'login', component: LoginComponent },
    { path: 'members', component: MembersComponent },
    { path: '', component: HomeComponent },
    { path: '**', redirectTo: '' }
];

...
imports: [
    BrowserModule,
    RouterModule.forRoot(routes)
],

Set the links in the app.component.html using routerLink like this:

<a class="navbar-item" [routerLink]="['']">Home</a>
<a class="navbar-item" [routerLink]="['/login']">Login</a>
<a class="navbar-item" [routerLink]="['/members']">Members</a>

If all is fine, you should see this in your browser:

Login

Replace the contents of the login.component.html with:

<section class="hero">
  <div class="hero-body has-text-centered">
    <form [formGroup]="form">
      <div class="columns">
        <div class="column"></div>

        <div class="column is-3">
          <div class="field">
            <label class="label is-pulled-left">Email</label>
            <div class="control">
              <input class="input" type="text" placeholder="[email protected]" formControlName="email" name="email">
            </div>
          </div>
        </div>

        <div class="column"></div>
      </div>

      <div class="columns">
        <div class="column"></div>

        <div class="column is-3">
          <div class="field">
            <label class="label is-pulled-left">Password:</label>
            <div class="control">
              <input class="input" type="password" formControlName="password" name="password">
            </div>

            <br>
            <br>
            <a class="button is-primary is-medium is-fullwidth" (click)='login()'>Login</a>
          </div>
        </div>

        <div class="column"></div>
      </div>
    </form>
  </div>
</section>

and add login.component.ts with:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
    form: FormGroup;

    constructor(private fb: FormBuilder) {
        this.form = this.fb.group({
            email: ['', Validators.required],
            password: ['', Validators.required]
        });
    }

    ngOnInit() {
    }

    login() {
        console.log('Clicked the Login button');
    }
}

You may notice that we used a bunch of imports from @angular/forms, so we also need to add it in app.module.ts in the imports array:

...
imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forRoot(routes)
],
...

Before we go to the actual authentication section, let’s just fix the Home and Members area slightly.

Home and Members

Update the HTML files to the following content:

home.component.html:

<section class="hero" id="hero">
  <div class="hero-head"></div>
  <div class="hero-body">
    <div class="container has-text-centered">
      <h1 class="is-1 title">
        Welcome to JWT Angular Auth!
      </h1>
    </div>
  </div>
</section>

members.component.html:

<section class="hero" id="hero">
  <div class="hero-head"></div>
  <div class="hero-body">
    <div class="container has-text-centered">
      <h1 class="is-1 title">
        Members area
      </h1>
    </div>
  </div>
</section>

Go

Our backend is written in Golang, and it looks like this:

package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
    "github.com/rs/cors"
)

const (
    PORT   = "1337"
    SECRET = "42isTheAnswer"
)

type JWTData struct {
    // Standard claims are the standard jwt claims from the IETF standard
    // https://tools.ietf.org/html/rfc7519
    jwt.StandardClaims
    CustomClaims map[string]string `json:"custom,omitempty"`
}

type Account struct {
    Email    string  `json:"email"`
    Balance  float64 `json:"balance"`
    Currency string  `json:"currency"`
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", hello)
    mux.HandleFunc("/login", login)
    mux.HandleFunc("/account", account)

    handler := cors.Default().Handler(mux)

    log.Println("Listening for connections on port: ", PORT)
    log.Fatal(http.ListenAndServe(":"+PORT, handler))
}

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello from Go!")
}

func login(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Println(err)
        http.Error(w, "Login failed!", http.StatusUnauthorized)
    }

    var userData map[string]string
    json.Unmarshal(body, &userData)

    // Demo - in real case scenario you'd check this against your database
    if userData["email"] == "[email protected]" && userData["password"] == "admin123" {
        claims := JWTData{
            StandardClaims: jwt.StandardClaims{
                ExpiresAt: time.Now().Add(time.Hour).Unix(),
            },

            CustomClaims: map[string]string{
                "userid": "u1",
            },
        }

        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
        tokenString, err := token.SignedString([]byte(SECRET))
        if err != nil {
            log.Println(err)
            http.Error(w, "Login failed!", http.StatusUnauthorized)
        }

        json, err := json.Marshal(struct {
            Token string `json:"token"`
        }{
            tokenString,
        })

        if err != nil {
            log.Println(err)
            http.Error(w, "Login failed!", http.StatusUnauthorized)
        }

        w.Write(json)
    } else {
        http.Error(w, "Login failed!", http.StatusUnauthorized)
    }
}

func account(w http.ResponseWriter, r *http.Request) {
    authToken := r.Header.Get("Authorization")
    authArr := strings.Split(authToken, " ")

    if len(authArr) != 2 {
        log.Println("Authentication header is invalid: " + authToken)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    jwtToken := authArr[1]

    claims, err := jwt.ParseWithClaims(jwtToken, &JWTData{}, func(token *jwt.Token) (interface{}, error) {
        if jwt.SigningMethodHS256 != token.Method {
            return nil, errors.New("Invalid signing algorithm")
        }
        return []byte(SECRET), nil
    })

    if err != nil {
        log.Println(err)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    data := claims.Claims.(*JWTData)

    userID := data.CustomClaims["userid"]

    // fetch some data based on the userID and then send that data back to the user in JSON format
    jsonData, err := getAccountData(userID)
    if err != nil {
        log.Println(err)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    w.Write(jsonData)
}

func getAccountData(userID string) ([]byte, error) {
    output := Account{"[email protected]", 3.14, "BTC"}
    json, err := json.Marshal(output)
    if err != nil {
        return nil, err
    }

    return json, nil
}

⚠️ I’m not a Go expert (yet), so this code would be written way more idiomatic by someone who’s using the language longer. But, when confronted with such thoughts yourself, remember this: “Perfect is the enemy of good”, and it’s way better to learn by doing and getting stuff ‘out there’ and getting feedback, than to ‘wait x months until you master a language’.

So, here goes my best attempt at explaining what the code does, from top to bottom:

package

package main

First, we have the package statement. Every Go program must have a main package.

imports

import (
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
    "github.com/rs/cors"
)

Then we have the imports. All of the imports, except for jwt and cors are from the standard Go library. If you’re using an editor like VS Code, or an IDE like GoLand, then these imports are added automatically as you save your code.

One thing I love about Go is the auto code format, so finally, some language where there will be no debate about whether the brackets in ifs go on the same line or in the next. Consistency FTW!

constants

const (
    PORT   = "1337"
    SECRET = "42isTheAnswer"
)

Then we have two constants: PORT and SECRET. It is not a practice in Go to have all uppercase letters for constants, but I’m blindly sticking to that habit it seems.

structs

type JWTData struct {
    // Standard claims are the standard jwt claims from the IETF standard
    // https://tools.ietf.org/html/rfc7519
    jwt.StandardClaims
    CustomClaims map[string]string `json:"custom,omitempty"`
}

type Account struct {
    Email    string  `json:"email"`
    Balance  float64 `json:"balance"`
    Currency string  `json:"currency"`
}

Next, we have two structs: JWTData and Account. The JWTData struct, along with some standard fields (claims) has an additional CustomClaims map, that can hold key-value pairs of type string. We will use this data type to add our own custom claims (userid).

The Account struct is used as an example structure for responding to the logged in user once he’s logged in and comes to the Members page. It contains the Email, Balance and Currency fields.

main

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", hello)
    mux.HandleFunc("/login", login)
    mux.HandleFunc("/account", account)

    handler := cors.Default().Handler(mux)

    log.Println("Listening for connections on port: ", PORT)
    log.Fatal(http.ListenAndServe(":"+PORT, handler))
}

In the main function we ‘register’ the handlers for our API. If we presume that this Go program would be running on a domain http://api.boringcompany.com, then the request to that URL would be handled by the hello function that we’ll show below. If the request is sent to the http://api.boringcompany.com/login URL, it would be handled by the login function that we’ll show below, etc. Finally, we print the message via the log and start the server with the http.ListenAndServe function.

The CORS handler is necessary only when developing locally. If you’ll do that, then I also recommend the CORS plugin for the browser you’re using (here is the one that I use for Chrome).

hello handler

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello from Go!")
}

This is a simple function that outputs Hello from Go! back to the user when he hits our main API URL.

login handler

func login(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Println(err)
        http.Error(w, "Login failed!", http.StatusUnauthorized)
    }

    var userData map[string]string
    json.Unmarshal(body, &userData)

    // Demo - in real case scenario you'd check this against your database
    if userData["email"] == "[email protected]" && userData["password"] == "admin123" {
        claims := JWTData{
            StandardClaims: jwt.StandardClaims{
                ExpiresAt: time.Now().Add(time.Hour).Unix(),
            },

            CustomClaims: map[string]string{
                "userid": "u1",
            },
        }

        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
        tokenString, err := token.SignedString([]byte(SECRET))
        if err != nil {
            log.Println(err)
            http.Error(w, "Login failed!", http.StatusUnauthorized)
        }

        json, err := json.Marshal(struct {
            Token string `json:"token"`
        }{
            tokenString,
        })

        if err != nil {
            log.Println(err)
            http.Error(w, "Login failed!", http.StatusUnauthorized)
        }

        w.Write(json)
    } else {
        http.Error(w, "Login failed!", http.StatusUnauthorized)
    }
}

In the login function we first read the body of the request and parse out the email and password parameters. We then check this email/password combination and make sure it’s correct. Of course, for demo purposes it was done like that in the code; in real case scenario, you’d check this against your database most probably.

If the user credentials are correct, we prepare the claims where we use the standard ExpiresAt claim, and also we add our own custom claim of userid with the value u1.

Next, we use the jwt.NewWithClaims function to sign the header and the payload with the HS256 hashing algorithm and we use the SECRET as a key for that. Finally, we then return this token to the user in JSON format.

Otherwise, if any errors happen, we send back the unauthorized status with a failure message.

account handler

func account(w http.ResponseWriter, r *http.Request) {
    authToken := r.Header.Get("Authorization")
    authArr := strings.Split(authToken, " ")

    if len(authArr) != 2 {
        log.Println("Authentication header is invalid: " + authToken)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    jwtToken := authArr[1]

    claims, err := jwt.ParseWithClaims(jwtToken, &JWTData{}, func(token *jwt.Token) (interface{}, error) {
        if jwt.SigningMethodHS256 != token.Method {
            return nil, errors.New("Invalid signing algorithm")
        }
        return []byte(SECRET), nil
    })

    if err != nil {
        log.Println(err)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    data := claims.Claims.(*JWTData)

    userID := data.CustomClaims["userid"]

    // fetch some data based on the userID and then send that data back to the user in JSON format
    jsonData, err := getAccountData(userID)
    if err != nil {
        log.Println(err)
        http.Error(w, "Request failed!", http.StatusUnauthorized)
    }

    w.Write(jsonData)
}

func getAccountData(userID string) ([]byte, error) {
    output := Account{"[email protected]", 3.14, "BTC"}
    json, err := json.Marshal(output)
    if err != nil {
        return nil, err
    }

    return json, nil
}

In the account function we first read the Authorization header and take out the token. Then we make sure the token is valid and has not been tampered with, and we parse out the claims by using the jwt.ParseWithClaims function.

With the userID claim we fetch some data (using the getAccountData function) and then send that data back to the user in the JSON format.

Running the Go app

You can run this app locally on your computer with go run main.go. Of course, you need to have Go installed. You can check how to do that in this tutorial.

Finishing up the Angular frontend

Now let’s switch back to our Angular project and make actual requests to our API.

Auth service

Using Angular CLI, execute the following command in your terminal:

ng g service auth 

This now created two files for us:

create src/app/auth.service.spec.ts (362 bytes)
create src/app/auth.service.ts (110 bytes)

Copy the following code to the auth.service.ts file:

import { Injectable } from '@angular/core';
import { RequestOptions, Response } from '@angular/http';

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';

@Injectable()
export class AuthService {

    API_URL = 'http://localhost:1337';
    TOKEN_KEY = 'token';

    constructor(private http: HttpClient, private router: Router) { }

    get token() {
        return localStorage.getItem(this.TOKEN_KEY);
    }

    get isAuthenticated() {
        return !!localStorage.getItem(this.TOKEN_KEY);
    }

    logout() {
        localStorage.removeItem(this.TOKEN_KEY);
        this.router.navigateByUrl('/');
    }

    login(email: string, pass: string) {
        const headers = {
            headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Cache-Control': 'no-cache' })
        };

        const data = {
            email: email,
            password: pass
        };

        this.http.post(this.API_URL + '/login', data, headers).subscribe(
            (res: any) => {
                localStorage.setItem(this.TOKEN_KEY, res.token);

                this.router.navigateByUrl('/members');
            }
        );
    }

    getAccount() {
        return this.http.get(this.API_URL + '/account');
    }
}

AuthService consists of these functions:

  • login – we send the email/password that the user enters to the server and upon success, we store the token in local storage. Please note the warning that I gave in the theory part of this tutorial.
  • logout – we delete the token from local storage and redirect the user to the landing page
  • token – returns the token from local storage
  • isAuthenticated – returns true/false if the token exists in the local storage
  • getAccount – requests the user data and returns a promise

login component

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AuthService } from '../auth.service';

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
    form: FormGroup;

    constructor(private fb: FormBuilder, private authService: AuthService) {
        this.form = this.fb.group({
            email: ['', Validators.required],
            password: ['', Validators.required]
        });
    }

    ngOnInit() {
    }

    login() {
        const val = this.form.value;

        if (val.email && val.password) {
            this.authService.login(val.email, val.password);
        }
    }
}

The most important part is the login function that calls the AuthService login function passing it email and password. We use the FormBuilder in Angular to access form fields that in the HTML code look like this:

<section class="hero">
  <div class="hero-body has-text-centered">
    <form [formGroup]="form">
      <div class="columns">
        <div class="column"></div>

        <div class="column is-3">
          <div class="field">
            <label class="label is-pulled-left">Email</label>
            <div class="control">
              <input class="input" type="text" placeholder="[email protected]" formControlName="email" name="email">
            </div>
          </div>
        </div>

        <div class="column"></div>
      </div>

      <div class="columns">
        <div class="column"></div>

        <div class="column is-3">
          <div class="field">
            <label class="label is-pulled-left">Password:</label>
            <div class="control">
              <input class="input" type="password" formControlName="password" name="password">
            </div>

            <br>
            <br>
            <a class="button is-primary is-medium is-fullwidth" (click)='login()'>Login</a>
          </div>
        </div>

        <div class="column"></div>
      </div>
    </form>
  </div>
</section>

Notice <form [formGroup]="form"> and formControlName="email". In Angular we register the click handler like this: (click)='login()'.

members component

Members component is pretty simple:

<section class="hero" id="hero">
  <div class="hero-head"></div>
  <div class="hero-body">
    <div class="container has-text-centered">
      <h1 class="is-1 title">
        Members area
      </h1>

      <p>Email:
        <b>{{accountData?.email}}</b>
      </p>
      <p>Balance:
        <b>{{accountData?.balance}} {{accountData?.currency}}</b>
      </p>
    </div>
  </div>
</section>

We use it to show some data that we’ll get from the API. Very important part is the use of ? – this instructs Angular to not throw an error while it’s rendering the template in case the data doesn’t yet exist (as it will be the case since we’re fetching this data from an API).

The controller code looks like this:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth.service';
import { Router } from '@angular/router';

@Component({
    selector: 'app-members',
    templateUrl: './members.component.html',
    styleUrls: ['./members.component.css']
})
export class MembersComponent implements OnInit {
    accountData: any;
    constructor(private authService: AuthService, private router: Router) { }

    ngOnInit() {
        this.authService.getAccount().subscribe(
            (res: any) => {
                this.accountData = res;
            }, (err: any) => {
                this.router.navigateByUrl('/login');
            }
        );
    }

}

When the component loads, we send a request to the API, and upon the success, we save the data in the accountData variable that we then use in the template as we saw previously. If an error occurs, we forward the user to the landing page.

app.component.html

<nav class="navbar">
  <div class="container">
    <div class="navbar-brand">
      <a class="navbar-item">
        JWT Angular Login
      </a>
    </div>

    <div id="navbarMenuHeroA" class="navbar-menu">
      <div class="navbar-end">
        <a class="navbar-item" [routerLink]="['']">
          Home
        </a>
        <a class="navbar-item" [routerLink]="['/login']" *ngIf="!authService.isAuthenticated">
          Login
        </a>
        <a class="navbar-item" [routerLink]="['/members']" *ngIf="authService.isAuthenticated">
          Members
        </a>
        <a class="navbar-item" *ngIf="authService.isAuthenticated" (click)="authService.logout()">
          Logout
        </a>
      </div>
    </div>
  </div>
</nav>

<router-outlet></router-outlet>

<footer class="footer">
  <div class="container has-text-centered">
    <div class="content">
      From Croatia with ❤️
    </div>
  </div>
</footer>

The important part to note here is the use of *ngIf="!authService.isAuthenticated" to show/hide the navigation links based on the fact if the user is logged in or not.

The only thing we need to do in the ‘code’ file is to make sure we import the AuthService via the constructor: constructor(private authService: AuthService) { }.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './login/login.component';
import { MembersComponent } from './members/members.component';

import { AuthService } from './auth.service';
import { AuthInterceptorService } from './auth-interceptor.service';
import { CanActivateViaAuthGuard } from './can-activate-via-auth.guard';

const routes = [
    { path: 'login', component: LoginComponent },
    {
        path: 'members',
        component: MembersComponent,
        canActivate: [
            CanActivateViaAuthGuard
        ]
    },
    { path: '', component: HomeComponent },
    { path: '**', redirectTo: '' }
];

@NgModule({
    declarations: [
        AppComponent,
        HomeComponent,
        LoginComponent,
        MembersComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        ReactiveFormsModule,
        HttpClientModule,
        RouterModule.forRoot(routes)
    ],
    providers: [
        AuthService,
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AuthInterceptorService,
            multi: true
        },
        CanActivateViaAuthGuard
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

This file imports all the components that we’re using. As you can see, in the ‘declarations’ we list the components that we’re using, the imports contain imported components for working with forms or sending HTTP requests.

guards and interceptors

Finally, you may notice something new in the providers array, where with the usual AuthService we have two additional things defined (an interceptor service and an auth guard):

{
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptorService,
    multi: true
},
CanActivateViaAuthGuard

The interceptor service has one task: to intercept every request that goes from the app and add the token to that request in its header:

import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor } from '@angular/common/http';
import { AuthService } from './auth.service';

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {

    constructor(private injector: Injector) { }

    intercept(req, next) {
        const authService = this.injector.get(AuthService);
        const authRequest = req.clone({
            // tslint:disable-next-line:max-line-length
            headers: req.headers.set('Authorization', 'Bearer ' + authService.token)
        });

        return next.handle(authRequest);
    }
}

THe guard is also simple and it’s defined like this:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';

@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {
    constructor(private authService: AuthService) {

    }

    canActivate() {
        return this.authService.isAuthenticated;
    }
}

So, we define the so-called ‘canActivate’ guard which we use when we want to prevent the user from going to some route in the app to which he doesn’t have the access. We use this guard in the route definition to prevent the user from going to the /members link if he’s not logged in:

const routes = [
    { path: 'login', component: LoginComponent },
    {
        path: 'members',
        component: MembersComponent,
        canActivate: [
            CanActivateViaAuthGuard
        ]
    },
    { path: '', component: HomeComponent },
    { path: '**', redirectTo: '' }
];

When you have all of this wired up (and a Go program running locally), you should see:

Conclusion

We’ve covered a lot of ground in this long post:

  • we learned a bit about how JWTs work
  • we created our own JWT with code examples in JavaScript and Go
  • we made a full-fledged app with Angular 5 on the frontend and Go on the backend that uses JWTs for authentication
  • we made use of Angulars Guards and Interceptors

I hope this was enough to get you started and build upon this example.

If you have any questions, feel free to reach out in the comments.

#JWT authentication in an #Angular application with a #Go backend https://t.co/UpZgaOcJUb

— Nikola Brežnjak (@HitmanHR) February 19, 2018

Ionic3, JavaScript

How to create an Android Cordova plugin for showing Toast popups

TL;DR

In this post, I’m going to show you step by step how to build a Cordova plugin for Android that shows a native Toast popup.

You can check out the source code of the plugin here and the source of the demo Ionic app that’s using this plugin here.

In case you’re looking for the guide on how to write the Cordova plugin for the iOS platform, I wrote about it here.

plugin.xml

We start the process of plugin building by creating the plugin.xml file:

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-android-toast" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>AndroidToast</name>

    <description>Android Toast Plugin</description>
    <license>Apache 2.0</license>
    <keywords>android, toast</keywords>

    <engines>
      <engine name="cordova" version=">=3.0.0" />
    </engines>

    <js-module name="AndroidToast" src="www/AndroidToast.js">
        <clobbers target="AndroidToast" />
    </js-module>

    <platform name="android">
        <config-file target="config.xml" parent="/*">
            <feature name="AndroidToast">
                <param name="android-package" value="com.nikolabreznjak.AndroidToast" />
            </feature>
        </config-file>

        <source-file src="src/android/AndroidToast.java" target-dir="src/com/nikola-breznjak/android-toast" />
    </platform>
</plugin>

In this file you basically define:

  • the platform this plugin supports (<platform name="android">)
  • where the source files of your plugin will be (source-file elements)
  • where is the JavaScript file that will be the bridge from Cordova to native code (js-module tag src property)
  • what will be the plugin’s name by which you’ll reference it in the Cordova/Ionic code (<clobbers target="AndroidToast" />)

www/AndroidToast.js

Next comes the so-called ‘bridge’ file that connects the native and JavaScript side. It is common to put this file in the www folder. The contents of this file is as follows:

var exec = cordova.require('cordova/exec');

var AndroidToast = function() {
    console.log('AndroidToast instanced');
};

AndroidToast.prototype.show = function(msg, onSuccess, onError) {
    var errorCallback = function(obj) {
        onError(obj);
    };

    var successCallback = function(obj) {
        onSuccess(obj);
    };

    exec(successCallback, errorCallback, 'AndroidToast', 'show', [msg]);
};

if (typeof module != 'undefined' && module.exports) {
    module.exports = AndroidToast;
}

We created the AndroidToast function, which in other programming languages would basically be a class, because we added the show function on its prototype. The show function, via Cordova’s exec function, registers the success and error callbacks for the AndroidToast class and the show method on the native side that we’ll show now shortly. Also, we pass in the msg variable as an array to the native show function.

src/android/AndroidToast.java

The ‘native’ code is written in Java:

package com.nikolabreznjak;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import android.content.Context;
import android.widget.Toast;

public class AndroidToast extends CordovaPlugin {
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("show".equals(action)) {
            show(args.getString(0), callbackContext);
            return true;
        }

        return false;
    }

    private void show(String msg, CallbackContext callbackContext) {
        if (msg == null || msg.length() == 0) {
            callbackContext.error("Empty message!");
        } else {
            Toast.makeText(webView.getContext(), msg, Toast.LENGTH_LONG).show();
            callbackContext.success(msg);
        }
    }
}

In the implementation file, we define our functions. We only have the show and execute functions in our example. When writing Cordova plugins for Android, every function from the bridge file has to call the exec function, which then calls the execute function on the native side. Then, based on the action parameter, we decide which function needs to be called. In our case, if we determine that the show action was called, we pass through the arguments to the private show function, which then uses the native Toast.makeText function to display the Toast message.

When displaying the Toast, our show method needs access to the app’s global Context, which can be obtained using the webView object that we get from extending CordovaPlugin. This represents the running Cordova app, and we can get the global Context from there using: webView.getContext(). Other parameters to the makeText function define the text that we want to show and the duration of how long we want to show it.

At this point you could customize the toast as much as the native Toast component allows, there are no restrictions even though this is used via Cordova as a kind of a ‘wrapper’. Some additional stuff that you could do is listed in the official documentation.

package.json

In earlier versions of Cordova, this file wasn’t required. You can generate it automatically with the help of the plugman package (install it with npm install plugman -g in case you don’t have it):

plugman createpackagejson /path/to/your/plugin.

If you’re in the plugin folder, then the command is: plugman createpackagejson .. The package.json file in my case now looks like this:

{
    "name": "cordova-android-toast",
    "version": "1.0.0",
    "description": "Android Toast Plugin",
    "cordova": {
        "id": "cordova-android-toast",
        "platforms": [
            "android"
        ]
    },
    "keywords": [
        "android",
        "toast",
        "ecosystem:cordova",
        "cordova-android"
    ],
    "engines": [{
        "name": "cordova",
        "version": ">=3.0.0"
    }],
    "author": "Nikola Brežnjak<[email protected]> (http://www.nikola-breznjak.com/blog)",
    "license": "Apache 2.0"
}

Using the plugin

First, you need to install it. If you’re using Ionic:

ionic cordova plugin add cordova-android-toast

If you’re using Cordova:

cordova plugin add cordova-android-toast

In the code, you would show the toast message like this:

constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
        platform.ready().then(() => {
            var androidToast = new AndroidToast();
            androidToast.show(
                'This is some nice toast popup!',
                function(msg) {
                    console.log(msg);
                },
                function(err) {
                    console.log(err);
                }
            );

        });
    }

If you’re using the newest (currently 3) version of Ionic, then you would have to add this line: declare var AndroidToast: any; after the imports in app.component.ts (or any other file where you’ll use the plugin) before actually using it. If you’re using Ionic 1, you don’t need to do this.

As a final note, make sure you’re accessing the plugin after the platform.ready() fires, just so you make sure that the plugin is ready for use.

Running the demo locally

Clone this repo:

git clone https://github.com/Hitman666/cordova-android-toast.git

CD into the cloned project

cd cordova-android-toast

Install the dependencies:

npm install && bower install

Add the Android platform (please note that this process may take a while to complete):

ionic cordova platform add android

Add the plugin:

ionic cordova plugin add cordova-android-toast

Run the project on the device (if you have it connected):

ionic cordova run android

Run the project on the emulator:

ionic cordova emulate android

You should see something like this once the app runs on your device:

Conclusion

I hope this post gave you enough information so that you’ll be dangerous enough to go and fiddle with the Android Cordova plugin building yourself ?

If you have any questions, feel free to reach out.

Page 14 of 51« First...10«13141516»203040...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