Quantcast
Channel: Devdactic – Ionic Tutorials
Viewing all 183 articles
Browse latest View live

Rapid Prototyping with Ionic 2 and Node.js – Part 1

$
0
0

Do you know how fast you can actually develop a really solid MVP prototype including a frontend and working backend these days? It’s amazing.

In this 3 part series I will share how I recently assembled a fully working prototype in only 3 days using node.js as the backend and Ionic 2 as the frontend of our MVP.

The Plan

The 3 parts of the series can be found below:

Rapid Prototyping with Ionic 2 and Node.js – Part 1: The Node.js Backend
COMING SOON! Rapid Prototyping with Ionic 2 and Node.js – Part 2: The Ionic 2 Frontend
COMING SOON! Rapid Prototyping with Ionic 2 and Node.js – Part 3: Deployment of your Components

If you want to stay up to date and get noticed once the other articles are out, make sure to leave your email in the box below!

In the first part we will start with a simple Node.js backend including a MongoDB database for holding some information.

Inside the second part we develop the Ionic 2 app and connect to our backend to retrieve the data.

As all of this is only working locally, we need a way to get this out in the hands of friends and customers so inside the third part we will take care of the deployment and actually getting our work into the hands of others!

If you got any questions along the way simply leave a comment. Let’s get the fun started!

Setting up Node and MongoDB Server

First of all make sure you have Node.js installed on your machine. Additional we will use a MongoDB to hold our data, so go ahead and install it as well following the instructions.

To test our app later I always recommend to use the Postman Extension which makes it really easy to test any REST API.

Finally, to inspect your MongoDB it’s convenient to have some GUI for the database so I picked Robomongo for that!

You don’t need all of these tools, but of course you need Node.js and MongoDB created to actually run our server.

Starting a new Node.js Server

To start a new Node.js server you have to run only one command which will first of all create your package.json. Afterwards we install the needed npm packages and finally we add 4 files that will be filled with everything we need later.

While the npm creation runs you will get asked many questions. Most of them can be skipped by pressing enter using the default value, but make sure to set the entry point of your app to server.js. Of course you can change it later inside the package.json, but why not do it right in the first place here.

Now go ahead and run:

npm init
npm install --save morgan cors express errorhandler mongoose body-parser helmet
touch server.js
touch todo.js
touch todo-routes.js
touch config.json

We are now ready to fill all these beautiful files with some great code!

Creating the Database Model using Mongoose

In order to interact with our database we use the Mongoose npm package. The way to use the database is to have a scheme defined that represents documents in the database.

In our case, we define a simple TodoSchema which represents a todo with a text and date.

Additional we add a pre function that will always be executed before the object is saved to the database. Here we can change things, like in our case set the created_at variable to the current date.

Finally we export that schema so the rest of our app can actually use it. Now go ahead and add the following to the todo.js:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TodoSchema = new Schema({
    text: {
        type: String,
        required: true
    },
    created_at: Date,
});

TodoSchema.pre('save', function (next) {
    var todo = this;
    // get the current date
    var currentDate = new Date();

    // if created_at doesn't exist, add to that field
    if (!todo.created_at) {
        todo.created_at = currentDate;
    }
    next();
});

module.exports = mongoose.model('Todo', TodoSchema);

We also created a config file which holds the url to our database. Currently we only use the localhost, but this file will become more useful in the 3. part of the series.

For now, open the config.json and insert:

{
  "database": "mongodb://localhost/devdactic-rapidbackend"
}

Make sure to start your MongoDB (on Mac simply run mongod from the CL) in order to get a connection from our app to the database!

Adding Routes with Express

The data model is finished, let’s continue with the actual REST routes for our app.

In our case, we will define 3 different routes:

  • GET todos: Get a list of all todos in the database
  • POST todos: Create a new todo and save to the database
  • DELETE todos/:todoId: Delete a specific todo from the database by its ID

We could have these routes inside the server file, but to keep a clean structure we put them in an appropriate place, which is in our case the todo-routes.js so go ahead and insert:

var express = require('express');

var app = module.exports = express.Router();

var Todo = require('./todo');

// POST
// Create a new Todo
app.post('/todos', function (req, res) {
  if (!req.body.text) {
    return res.status(400).send({ "success": false, "msg": "You need to send the text of the todo!" });
  }

  var newTodo = new Todo({
    text: req.body.text
  });

  newTodo.save(function (err) {
    if (err) {
      console.log("some error: ", err);
      return res.json({ "success": false, "msg": "Error while creating Todo", "error": err });
    }
    res.status(201).send({ "success": true, "msg": 'Successful created new Todo.' });
  });
});

// GET
// Get all open Todos
app.get('/todos', function (req, res) {
  Todo.find({}, function (err, todos) {
    if (err) {
      return res.json({ "success": false, "msg": "Error while creating Todo", "error": err });
    }

    res.status(200).send({ "success": true, "result": todos });
  });
});

// DELETE
// Remove one todo by its ID
app.delete('/todos/:todoId', function (req, res) {
  var lectionId = req.params.todoId;
  if (!lectionId || lectionId === "") {
    return res.json({ "success": false, "msg": "You need to send the ID of the Todo", "error": err });
  }

  Todo.findByIdAndRemove(lectionId, function (err, removed) {
    if (err) {
      return res.json({ "success": false, "msg": "Error while deleting Todo", "error": err });
    }
    res.status(200).json({ "success": true, "msg": "Todo deleted" });
  });
});

To create a new todo, we create a new Todo object which is our mongoose scheme that we have exported. This object already has different functions, like save to write the object to the database. If this operations is successful we return a success and are finished here.

To get all todos we can use the Todo schema again and call find without any specific parameters. Normally you could specify an object to filter here, but in our case we want all the todos inside the database. The return and error handling is pretty much the same in all of our 3 routes.

Finally, to delete a todo we get an id through the request parameters which we use then for the findByIdAndRemove function of our TodoSchema.

That’s already everything for some very simple CRUD (well not the U but..) operations on our MongoDB, now we only need to get this server started!

Starting our Node.js Server

We have created the model and the routes, but we actually need to define our server and apply some of our installed packages to make life easier.

Stuff like helmet (protects your app) and cors (you know about CORS with Ionic apps) are just really helpful and can be added within a few lines.

Finally, we establish the Mongoose connection to the database using our config.json and call use on our todo-routes so the app applies all the routes to our server. Now we can create the server and print out a log if everything was successful.

Go ahead and add everything to your server.js:

var logger = require('morgan'),
  cors = require('cors'),
  http = require('http'),
  express = require('express'),
  errorhandler = require('errorhandler'),
  bodyParser = require('body-parser'),
  mongoose = require('mongoose'),
  helmet = require('helmet'),
  config = require('./config.json');

var app = express();
app.use(helmet())

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());

if (process.env.NODE_ENV === 'development') {
  app.use(logger('dev'));
  app.use(errorhandler())
}

var port = process.env.PORT || 3001;

mongoose.Promise = global.Promise;
mongoose.connect(config.database);

app.use(require('./todo-routes'));

http.createServer(app).listen(port, function (err) {
  console.log('listening in http://localhost:' + port);
});

If your package.json has the correct entry point you can start your server now simply by running npm start!

You can see a detailed video including how to use Postman and Robomongo below.

Conclusion

The development of a very basic REST API using Node.js, Express and MongoDB is extremely fast and is a solid approach to rapid prototyping. The developed assets can build the base for the future project and can be expanded to a full-blown backend over time, so it’s not a quick shot for a prototype and starting over again but a very reasonable start for a modern backend API project.

Happy Coding,
Simon

The post Rapid Prototyping with Ionic 2 and Node.js – Part 1 appeared first on Devdactic.


There is no Business like Blog Business

$
0
0

When I started this blog over 2 years ago I did not image what would happen over the next years. In 2014, I thought I’m already late to this blogging thing and that it would be a relict of 2007 like MySpace, but I was definitely wrong.

From the outside it looks like blogging is maybe something for teenagers to share their stories, or that nobody reads a blog anymore today. Both are completely wrong, and there is no sign that the popularity of blogs will end very soon.

What you can see from the outside is only the tip of the iceberg. In this article we will see what’s behind all of this and why you can actually build a blog business of your dreams even today.

Why Blogging Business is so much more than just writing

A blog itself is not yet a business nor is he making you any money in general. You have to think of a blog as the central hub of your brand.

Ok this might sound strange, especially when you compare yourself with big brands, but you or your platform is a brand as well (not so big as Apple maybe, but that doesn’t matter).

If you are a software developer, there are many good reasons to start a blog. You can get so much out and at the same time build your own platform for your services, products or whatever it is that you are going to sell.

Today almost every big brand has some sort of blog to release fancy content that drives traffic to their products. Same counts for your personal brand. You are not primarily making the big money from the blog, but from everything related to the blog like consulting services, books, online courses and more.

That’s finally the reason and the way to build your own blog business by starting from a small blog. With increasing traffic you can add more products, you get more popularity and finally you will find new ways to earn money by completely living from your blog and everything connected to it!

You can see, what might once start as a small idea or hobby can become a huge project over time. There are a few things you need to learn on your way to a successful blog business, and these are a few areas of special interest.

What you can expect to learn

It’s not that you have to learn about all of these topics below, but you actually want to learn them at some point. If you treat your blog not just like a little diary but like your own business, there are tactics and reasonable changes that you should apply to increase the chances of becoming successful.

When I started out, I never heard of anything specific about these topics but 99% of high valuable information is out there for free, you only need to find and consume it! We will see some great sources of information later.

The areas I’m talking about are things like:

  • SEO (Search engine optimisation): How can you rank higher in Google for specific keywords?
  • Social Media Marketing: How to connect with others, share your content regularly and increase traffic
  • Building an email list: The most recommend action item of all
  • Selling products: How and what to sell if you don’t want to sound too sleazy?

There are many more tiny lessons you will learn, but these are a few core competencies where you can expect personal growth.

The knowledge you gain over time is priceless!

Of course you don’t have to know everything at once. Before I actually started an email list it took me some time (and nobody was interested before). But once you see the result of your learnings, you know you are on the right path.

This blog might seem like a place of some tutorials and content, but behind the scenes all of these different parts need attention. You need to increase your traffic, visitors, keep them engaged, get them on your list and finally hopefully sell your services.

“Never regret. If it’s good, it’s wonderful. If it’s bad, it’s experience.” – Victoria Holt

Whether you enjoy tinkering and learning new stuff depends on you, but learning about something new has never turned out negative for me. So if you are interested in building your own little business, here are a few of the key resources that helped me to grow Devdactic over time.

How to build your own Blog Business from Scratch

If you start at zero, it’s a pretty good idea to just spin up a WordPress blog and start right away. There is no better time to start something than today, so just get out and start small.

If you are looking for a good hosting, I can highly recommend Digital Ocean (Affiliate Link) on which this blog runs. They offer very cheap VPS which you can also use for all kinds of developers activities (like to deploy a simple Node.js server!).

There are enough great sites out there that will help you to grow your blog, how to blog and everything else, but a few stand out to me. These sites and podcasts really helped me to get from “hobby blog” to a more serious lifestyle business oriented approach.

Smart Passive Income

The first and best podcast I know about generating income on the side. Pat Flynn is the master of this, and the site plus the podcast are pure gold in the beginning!

Side hustle nation

Side hustle nation is all about ways to build up your own little side hustle. Whatever direction you want to take, I bet Nick Loper had someone on the podcast that could act as an archetype for your own journey.

The Fizzle Show

The guys at Fizzle made many hours of my commute: Inspiring, funny and entertaining. Besides their podcast they deliver a huge amount of value through their blog and the membership site they run. If you want to seriously start you business, joining their side is a big step forward (if you actually use the material).

Those are my 3 favorite sites and podcast that helped me to grow and shape what is now Devdactic.

If you are interested in starting and building out your own blog business or “side hustle” than I recommend you start with the resources of these epic folks!

What it takes to be successful

Everyone can start a WordPress blog or write some posts, but what differentiates you from the rest is your motivation and ambitions. You can blog occasional but don’t expect to get anywhere without some clear goals.

To be consistent is one of the biggest reasons some people succeed. Show up, week after week. Stay in contact and deliver value, over and over and over again. If people like what you do and you can help them, they will more likely follow you and your business!

Your business is always about creating value for people. That’s not a secret, it’s the rule for every startup or company. So if you want to increase the chances of becoming successful, make sure you deliver value to your audience and not just pure air.

Don’t fear to step outside
. The species of developers is not known for being very open or going out a lot. Sharing your voice online is something many see as a big obstacle or fear, but it will help you to grow both online and in real life. When I created my first YouTube videos I had to do the start like 5 times because I was so freaking nervous to record myself.

Finally, create stuff that you enjoy doing!

If other people can see the joy you put into the work, they will more likely also enjoy the product, post or whatever you created. Also, doing something you don’t really like will come back to you at some point because you just can’t stand it anymore and your business fails because you lose motivation.

Start today

A blog is more than just a website with some random post, it can grow way beyond into a complete lifestyle business. It’s up to you to decide what you do with your skills and how you can help others in their life.

If you always thought about starting something, why not start today?

Tomorrow you wish you had started yesterday.

Happy Coding,
Simon

The post There is no Business like Blog Business appeared first on Devdactic.

Rapid Prototyping with Ionic 2 and Node.js – Part 2

$
0
0

Ionic 2 is an awesome framework for building out your MVP. Not only you can benefit from the speed of the framework, you also get the advantages of Angular 2 and a cross platform app for iOS and Android in no time.

In this second part of our 3 part series we focus on building the frontend for our prototype.

All of the 3 parts of the series can be found below:

Rapid Prototyping with Ionic 2 and Node.js – Part 1: The Node.js Backend
Rapid Prototyping with Ionic 2 and Node.js – Part 2: The Ionic 2 Frontend
COMING SOON! Rapid Prototyping with Ionic 2 and Node.js – Part 3: Deployment of your Components

If you want to stay up to date and get noticed once the other articles are out, make sure to leave your email in the box below (and grab a template of this article for free)!

In the first part we developed a simple REST API using Node.js to save some data in our database. It’s time to actually send those requests from an Ionic 2 app, so let’s develop our prototype and connect it in this part.

Make sure you have the server from the first series up and running to completely follow along this tutorial!

Starting a Blank Ionic 2 App

We start with a simple, blank Ionic 2 app and generate 2 providers which will help to configure our app and backend later. Start with the commands below:

ionic start devdactic-rapidfrontend blank --v2
cd devdactic-rapidfrontend
ionic g provider AppSettings
ionic g provider TodoService

As we have created new providers we need to import them into the providers array of our src/app/app.module.ts, the rest of that file stays pretty much the same:

import { AppSettings } from './../providers/app-settings';
import { TodoService } from './../providers/todo-service';
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

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

We can now start to fill all these files with the code for our MVP Ionic 2 app and connect it to our backend.

Building the Backend Connection Provider

If you have developed an app with a backend before you know that most of the time there are multiple staging environments like development, qa, testing, live or how many instances you have.

To easily change connection between different systems, we keep the url to these systems in one file to change that url later in only on place. That’s the reason why we created the AppSettings provider.

Inside we define the apiUrl which currently points to our local Node.js server from part 1. The only function of this provider is to return this url (at the moment) so go ahead and replace your src/providers/app-settings.ts:

import { Injectable } from '@angular/core';

const CONFIG = {
  apiUrl: 'http://127.0.0.1:3001/',
};

@Injectable()
export class AppSettings {

  constructor() {
  }

  public getApiUrl() {
    return CONFIG.apiUrl;
  }
}

The second provider we generated handles all the connections and calls to the backend. Again, it’s a good idea to structure your project in a good manner and keep calls like these in a separate file from your page component which directly interacts with the view.

In the first tutorial we created 3 routes:

  • Get all todos
  • Post a new todo
  • Delete a todo by it’s id

These routes are now transformed to the functions of the provider, each mapping the result to a JSON object and returning the Observable. Open your src/providers/todo-service.ts and insert:

import { AppSettings } from './app-settings';
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class TodoService {
  apiUrl = this.appSettings.getApiUrl();

  constructor(public http: Http, public appSettings: AppSettings) {
  }

  public getTodos() {
    return this.http.get(this.apiUrl + 'todos')
      .map(response => response.json().result);
  }

  public addTodo(newTodo) {
    return this.http.post(this.apiUrl + 'todos', {'text': newTodo})
      .map(response => response.json());
  }

  public deleteTodo(todoId) {
    return this.http.delete(this.apiUrl + 'todos/' + todoId)
      .map(response => response.json());
  }
}

Our connection to the backend is now more or less ready, we just need to use all of those beautiful functions! Let’s finish our MVP by building out the simple view for our todo list.

Creating the View for our Frontend

Inside our view we want to display a list of todos we get from the backend. Additional we need a function to create a new todo, and we also want to be able to delete a todo by its id.

Loading all the todos is just a call to our todoService and only setting our todos variable to the result which is already an observable. THe view will handle the rest of it!

To create a todo we will use the AlertController of Ionic 2 with a simple input. On save, the handler of the button will call our todoService.addTodo and subscribe to the result to update the view once it is finished.

Removing a todo is now as simple as again calling our todoService and passing the id of a todo (we will select the id in the view in the next step).

Finally we have a simply function to show a little toast message, but nothing really fancy here. Now go ahead and add everything to your src/app/pages/home/home.ts:

import { TodoService } from './../../providers/todo-service';
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { NavController, AlertController, ToastController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  todos: Observable<any>;

  constructor(public navCtrl: NavController, public todoService: TodoService, public alertCtrl: AlertController, public toastCtrl: ToastController) {
    this.loadTodos();
  }

  loadTodos() {
    this.todos = this.todoService.getTodos();
  }

  addTodo() {
    let prompt = this.alertCtrl.create({
      title: 'Add Todo',
      message: "Enter the text for your new todo",
      inputs: [
        {
          name: 'text',
          placeholder: 'Buy Milk'
        },
      ],
      buttons: [
        {
          text: 'Cancel'
        },
        {
          text: 'Save',
          handler: data => {
            this.todoService.addTodo(data.text).subscribe(data => {
              this.showToast(data.msg);
              this.loadTodos();
            });
          }
        }
      ]
    });
    prompt.present();
  }

  removeTodo(id) {
    this.todoService.deleteTodo(id).subscribe(data => {
      this.showToast(data.msg);
      this.loadTodos();
    })
  }

  private showToast(message: string) {
    let toast = this.toastCtrl.create({
      message: message,
      duration: 3000
    });
    toast.present();
  }
}

The last missing step is to show the items inside our view.

For the todos we create a simple list which has ion-item-sliding items so we can easily add a sliding option button which will reveal the delete button.

To add a todo we use the ion-fab button which floats above our content at the desired position, which is in our case right and bottom. This component makes it super easy to add material design buttons and it looks really good out of the box!

Add all of the code below to your src/app/pages/home/home.html now:

<ion-header>
  <ion-navbar>
    <ion-title>
      Devdactic Rapid Todos
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item-sliding *ngFor="let todo of todos | async">
      <ion-item>
        {{ todo.text }}
      </ion-item>
      <ion-item-options side="right">
        <button ion-button color="danger" (click)="removeTodo(todo._id)">
        <ion-icon name="trash"></ion-icon>
        Delete
      </button>
      </ion-item-options>
    </ion-item-sliding>

  </ion-list>

  <ion-fab right bottom>
    <button ion-fab (click)="addTodo()"><ion-icon name="add"></ion-icon></button>
  </ion-fab>
</ion-content>

Now your app is ready, connected to the backend and it should show all the todos of your database. Make sure the server from the first part is up and running and have fun playing with your new MVP Ionic app with a real backend!

You can see all the steps described again in detail in the video below.

Conclusion

Ionic 2 with Angular 2 gives even your dummy apps or prototypes a clean code and architecture just by how the framework was designed. With only basic functions we were able to come up with a clean app that can now interact with our backend and be the starting point for future features of our MVP.

Of course you could add some more error handling, but for this version we simply hope for the best all the time.

Next time we will bring together the backend and frontend in a live environment meaning other people can actually get their hands on our MVP!

Happy Coding,
Simon

The post Rapid Prototyping with Ionic 2 and Node.js – Part 2 appeared first on Devdactic.

The Beginning of the Ionic Academy

$
0
0

A few weeks ago the Ionic Academy was announced and the response was incredible. You really want a platform to learn and interact and that’s what the Ionic Academy will become – designed for the actual needs of the people. But there is a lot more that goes into such a launch.

In this post I will share some “behind the scenes” information about this announcement and everything related to the Academy. It’s not an easy endeavour to launch a membership site, so if anyone has ever thought about it this post will also give some advice on the steps in the beginning!

Finally we take a look at what the Academy will become, but for the moment we start with a very basic question:

Why the Ionic Academy?

On this blog I have shared countless tutorials including video material, courses and even a book on Ionic 2. All of this was helpful, but I want to be even closer to my audience.

Through the Ionic Academy it will be more sort of a guided learning. There will be more interaction between people, faster and more personal contact then a blog and email would allow.

It is more flexible then a book because it will develop over time and the course library will fill up more and more as time goes by. Also, this will help to make the courses and material eve more tailored towards the needs of the people by giving them a voice.

Finally, it will be a better mix of different learning elements so people can really take action on what they learned. This is what makes the Ionic Academy so different from the material and tutorials before!

Before Starting a Membership Site

Before actually starting any new project there is a learning phase. I tend to keep it as short as possible as I’m more action oriented and want to get started wants my fire is burning.

Of course I did not wake up with the thought “let’s start an Academy!” but planned ahead and already aligned a few steps before, so here is what led to the announcement of the Ionic Academy.

History: My book was finished and I was looking at new ways to help my audience. The release of Ionic 2 was near and I knew people would immediately fall in love with it. And inside I was thinking about some sort of membership site for quite some time.

After reading a lot of material on the Membership Guys I came to the conclusion that I would never feel completely ready for a membership site, so why not just do it?

First of all, you need some serious hosting. In this case I picked Namecheap (Affiliate Link!) because I had really bad experiences with a hoster many professional bloggers recommend. So far I’m really happy with their Support and the service I get there.

Then you go ahead to install all kind of software, so in this case it was:

  • WordPress: Of course the blogging platform almost everyone uses
  • MemberPress: A plugin to turn WP into a membership site
  • Thrive: A building to create better landing pages
  • iP.Board: An excellent and robust self hosted forum software

After installing and connecting all of those components I already started setting up membership rules and payment providers.

Wait what?

Once I’m in the flow nothing can stop me and before I know what I’m doing I finish steps 10, 11 and 12 but actually need steps 3-9. But what I like about this approach is to be sure everything works before continuing. It’s just how I work on projects sometimes.

It’s a sort of experiment if everything actually can work, and when I see I’m able to do it I definitely go for it. And that meant in this case getting the site out to you!

The landing page was created on the day I announced it to my email list of more than 11.000 subscribers and what followed blew me away.

Start Before You Are Ready

You are never more ready than now.

“Do what you can, with what you have, where you are.” –
Theodore Roosevelt

You will most likely never feel confident enough about a risky idea, so the best idea is to simply start. That’s the approach I took to validate if there was actual interested in the Academy.

All you need to test your idea is to set up a squeeze page (landing page), add an email sign-up button and get the link out!

I could have worked days or weeks more behind the curtain, but would anybody be interested at all?

That’s why I choose to make it public, plus my I set my own deadline (which might have been a bit hard looking back) to be sure I will stick to this project and deliver in time.

When you announce something big you have a mixed feeling of hope and panic whether it will work out, but as I was waiting in my Google Analytics I was already blown away after a few minutes..

ionic-academy-start-traffic

Seems like my idea sounds interesting and people actually like it. I was relieved and to the same degree again in panic mode because I now really do have to deliver in time.

But I was glad to be prepared for this because the Academy is about the people and their needs, not my special interests.

Content Designed by Members

The content inside the Ionic Academy was by no means ready at this point. But that was as well the intention of the squeeze page, to capture emails of interested people and ask them for help.

To engage with people I created an autoresponder inside Convertkit (my email list provider) which would go out 1 day after the sign up and ask for 1 thing you would like to see inside the Academy. By now I got more than 40 responses and I am more than thankful for each of them.

Those emails helped to shape the initial plan for the course library of the Ionic Academy as well as the general roadmap for projects and features.

The first days after announcing the Ionic Academy brought in more interested people then ever expected:

ionic-academy-convertkit

By now I have a pretty good picture of the interests of you. However, it’s impossible to come up with a solution for every special case, especially not in this very short timeline.

If you have any ideas or wishes you haven’t sent me, make sure to leave a comment below!

I definitely consider everything.

But I will continue to work hard on creating an initial library that helps the people first and foremost with actual problems they have.

The Content Plan

The Content plan is made by the people. I am really proud about this fact and hope the ones who join the Ionic Academy will feel the love that has gone into it.

Until the launch date a series of courses and hands-on projects will be ready inside the library of the Ionic Academy.

The content will be divided into 3 knowledge levels:

  • Beginner
  • Intermediate
  • Advanced

For each of these levels there will be different video courses and project challenges to apply your knowledge. You can simply start where you are and work you way through the topics in your own time.

Whenever you encounter problems, you can ask questions to the courses and projects.

The topics for the different levels are motivated by the email responses I got (and still get, thank you so much!) plus a few basic topics that just have to be inside.

The current learning plan is that you can go through the courses and afterwards apply your new knowledge in little projects.

For the future, the are even more scenarios possible like live hours and webinars, but for the beginning we KISS (keep it simple stupid).

Next Steps

At the time of writing this I am having a design contest to create a logo for the Ionic Academy on 99Designs from where I also got the Devdactic logo.

Besides that I’m looking for a video hosting solution where I currently favorite Vimeo so I can simply embed those videos private on the Academy.

Finally, of course I am working hard to create a lot of courses and projects for the opening day!

As Ionic 2 was released at the day of writing this, I am even more happy to go through all the topics again because you can learn so much if you teach something. An aspect I’m very thankful for.

The main focus for the upcoming weeks is also creating all course and project pages inside the Academy for the best possible user experience so you can easily manage your learning progress.

So this time definitely fells into my “create” goal for 2017.

What You Can Expect

So if you have sticked so far with me: thanks a lot! This was quite a long post and not a technical one.

The Ionic Academy will be a place to learn Ionic guided with tutorials, courses and social interaction between fellow developers who are doing the same just like you.

It’s about a creating a community of people who all have the same goal: Building awesome mobile apps using web technologies.

It’s not a place to spread hate, flame about other frameworks or starting a fight about nonsense.

Below you can see a first inside view of the Academy from one of the courses!

ionic-academy-preview-course
Sneak peek at the inside of the Ionic Academy

The creators of Ionic did not create Ionic to fight anyone nor to open a second war besides Apple vs Android some years.

They created Ionic to allow developers of all knowledge levels step into the development of mobile apps, so more and more people are able to build the solutions of tomorrow for all major platforms available.

Everyone is free to use the tools that get’s your job done in the best way. And for many people this means going hybrid!

For the Academy this also means that the path is not completely defined by now, it will grow with the interaction and engagement of the users.

Possible future ideas are webinars, live coding sessions or monthly challenges to get even more hands on experience with the thing you love the most: developing.

I hope you will enrich the community of the Ionic Academy like the Academy will help you along your Ionic coding journey.

Happy Coding,
Simon

The post The Beginning of the Ionic Academy appeared first on Devdactic.

Rapid Prototyping with Ionic 2 and Node.js – Part 3

$
0
0

If you have developed an app you want to get it out into the hands of other people. But what’s the easiest way to do so without already submitting your unfinished app? And what about your backend?

In this last part of our 3 part series we will see how to easily use an Ionic service to show your app to other people in nearly no time. Also we will deploy our Node.js backend to a server we can reach from everywhere (not just localhost).

All of the 3 parts of the series can be found below:

Rapid Prototyping with Ionic 2 and Node.js – Part 1: The Node.js Backend
Rapid Prototyping with Ionic 2 and Node.js – Part 2: The Ionic 2 Frontend
Rapid Prototyping with Ionic 2 and Node.js – Part 3: Deployment of your Components

How to get your MVP out?

There are different options to get our your app. The way described inside Ionic 2 From Zero to App Store is the standard iOS and Android procedure of alpha & beta staging. This official way involves having an iOS developer account as well as a Google Play Developer account.

If you have both of them, you can “simply” submit your apps and start an alpha or beta test with selected people before the app officially hits the app store. Simply means, you still have to insert a lot of details for your apps as they will be shown like regular store entries to your testers so it takes some time to provide that.

But there’s another less stressful way which involves the Ionic View service which we will use to provide access to our MVP.

What about the backend side?

It’s quite easy to hit npm start and happily connect your app to localhost, but of course you can’t start that same server on your local machine for people out there that are going to test your app. If you have your own server you can get the code deployed there, install all the needed packages for Node.js and add a redirect to the port of the running backend.

You say, although you might even have a server it won’t be that easy, and for others it’s likely to see only question marks if they had to deploy the server. That’s why we use the simple and (in the beginning) free to use service Heroku to deploy and run our app in really no time.

If you have never done it before you might be surprised how easy it can be to get out your complete functional app into the hands of others, so follow along the next steps to finally deploy our frontend and backend!

Upload your Node.js Server to Heroku

For this part you need the code from the first part of the series, so make sure you have the backend code ready for the next steps or go back to get it now!

First of all we will make our backend available. If you haven’t done yet, make sure to create a new account on Heroku (it’s free) to get started.

Once you are ready, we need to install the Heroku CLI so download it and follow the installation steps.

After we have installed the toolbelt (I think that was the previous name) we need to login to our account from the command line, so run

heroku login

Also, if your repository is not yet a Git repository we need to quickly init git and commit our current folder. In that case also run inside the folder of your backend app:

$ cd myapp
git init
# Initialized empty Git repository in .git/
git add .
git commit -m "my first commit"

If you already have a repository it’s quite easy to connect it to Heroku aswell, simply check out the Heroku Git setup guide.

We are now ready to create a new Heroku app. This will create a new instance inside your dashboard if you login to your account, and this is the place where we can now push our code to. Once we run the create command, Heroku actually set’s the remote URLs for our repository which you can directly display after running it.

To finally “deploy” your application, you need to push your git changes to the Heroku remote. You will see some logs from your deployment and hopefully read something like “success” in the end which is a good sign that something has worked. Now run these commands inside your backend folder:

$ heroku create
git remote -v
# heroku	https://git.heroku.com/.git (fetch)
# heroku	https://git.heroku.com/.git (push)
git push heroku master

We are almost finished, but remember that we used a local MongoDB

We need a MongoDB!!

Don’t panic, Heroku for the win. Heroku allows to easily configure add ons for your instance, and one of those is the Cloud MongoDB service mLab.

If you have your own isntance of MongoDB running somewhere you can of course use that, but if not simply follow the steps below to integrate mLab into your Heroku instance.

Configure mLab for Heroku

Inside your Heroku dashboard select the app of your backend. If you have multiple, make sure to select the right one!
prototyping-heroku-0
Inside the view of your app click on Configure Add-ons which will take you to a new screen.
prototyping-heroku-1
In the section Add ons simply start typing mongo or mlab until the entry shows up in the list below.
prototyping-heroku-2
Select the plan that fits you best. For this tutorial I simply picked Sandbox because we are only testing some stuff, so you can go with that option for now!
prototyping-heroku-3
After you have selected mLab the service should show up inside your add ons area and Heroku will show you a success message.
prototyping-heroku-4

You have now successful configured a MongoDB inside Heroku!
We can now (with a little trick) grep the URL for our database by running the following command inside our folder:

heroku config | grep MONGODB_URI

Remember our config.json inside the backend project? Edit this file now and insert the URL you got from the previous command.

{
  "database": "mongodb://<dbuser>:<dbpassword>@12356.mlab.com:55718/heroku_a123456"
}

Now commit and push to Heroku again and your backend is completely living in the cloud!

You can try to connect with Postman now, you can find your URL to the app online or again by using a simple command:

heroku info -s | grep web_url | cut -d= -f2

( thanks to Stackoverflow)

If you want to see how to see Postman requests go back to the first part and watch the video at the bottom of the post, I’m showing how to use Postman against your local backend so simply replace localhost with the URL to your new app.

Our backend is now in the cloud and accessible from everywhere, so it’s time to make our frontend Ionic 2 app ready now!

Publish your Ionic 2 App through Ionic.io

The current app we have built in the second part of this series is a fine little app, but we have 2 problems:

  • The app is using localhost as the backend
  • The app can only be installed directly to a device from our computer

What we want is the app to live in the outside world, so we need to tackle those 2 points now. We start with the first one as it’s the more easy one.

All we have to do is to change the route to the backend in exactly one file. That is some good planning!

Make sure you have the code of the app ready and open the src/providers/app-settings.ts so we can change the URL to our Heroku URL:

import { Injectable } from '@angular/core';

const CONFIG = {
  apiUrl: '',
};

@Injectable()
export class AppSettings {

  constructor() {
  }

  public getApiUrl() {
    return CONFIG.apiUrl;
  }
}

As all of our services simply use this route, we don’t have to change anything else here to switch from local backend to Heroku now!

This was the easy part, but in fact the next one is almost as easy as this with just a few steps more.

To get our MVP out in the hands of customers or testers we can use the Ionic Cloud and especially the Ionic View app.

If you haven’t used it make sure to get an account there, it’s free for the basic stuff we will use.

Through the Ionic.io platform we are now able to upload our app and share a link or email so other people can get the app through the Ionic View app (which they need to install).

To get your app connected to the cloud services, start in your apps directory and run:

ionic io init

This will create an app id and you can now find a new entry in the dashboard of your account.

Now go ahead an upload your app by running:

ionic upload

You will now get a feedback on the command line with a question to share your app. You can send out emails to your clients or your own account and grab the link inside to download your app from the Ionic View app!

That’s already everything to get your MVP out in the hands of your customers. Of course this is not the real submission, if you want to follow the complete path to the app store make sure to checkout From Zero to App Store where we go through the complete submission for iOS and Android!

Conclusion

We have finally done it! Your app can now live outside your localhost and others can use it with a connection to a real running backend.

I hope this 3 parts gave you an idea how fast you can actually developed a frontend and backend, and why using these technologies is a good idea for rapid prototype and releasing an MVP of your project.

If you need any help developing an MVP for your project or startup, let me know and I’ll be happy to work with you.

Happy Coding,
Simon

The post Rapid Prototyping with Ionic 2 and Node.js – Part 3 appeared first on Devdactic.

Behind the Scenes of Launching an Ionic 2 eBook

$
0
0

Last year in December I launched the Ionic 2 eBook “Ionic 2 – From Zero to App Store” which was the most successful product Devdactic ever had. There were a lot of considerations and countless hours of work that led to this release, most of them were never noticed by anyone.

In this post I will show what you can expect if you plan to write an eBook, which practices worked best for me and how you can get it all done while still working a full-time job.

Finding the Right Idea

Before starting any kind of project you need the right idea. And the right idea doesn’t mean it only looks good to you and you think everyone needs this.

If you only create what you think is useful you will most certainly fail. I did this in the past and lost months of work for nothing.

Learning from mistakes I did a survey (using Google Survey was totally fine) to ask all the readers of Devdactic about different interests and problems they have. And 155 persons filled out the survey, a lot more than I ever expected to take part, so thank you once again for your participation!

After they survey was finished it was time to aggregate the results and look for patterns.

ionic-survey-results

This was the critical step in which I discovered that more than a few people responded with they would like to go from zero to hero and most of them were as well interested in Ionic 2.

That’s when the idea for the book was born, created only by the problems of the readers!

Getting Shit Done

While this was already early in the year, I knew I wanted to release the book close to the release of Ionic 2 to prevent all kinds of errors due to different versions. So until summer I did not really start any writing for the book.

It was in the most relaxing moment 2016 right in this sport when I created my timeline.

At the beach of Mallorca I settled on a release date of the book because I wanted to finish it in 2016.

mallorca-book-planning

In retrospective this was most effective for some reasons:

First, a project takes always so much time as you have for it. If I had gave myself 1 year, the book would have taken 1 year. This is Parkinson’s law and it’s most of the time damn right.

“work expands so as to fill the time available for its completion” – Parkinson

Still, the timeline was realistic and now with the launch date in mind I was able to plan backwards.

When does which part, chapter, marketing page or email need to be ready?

Everything could be scheduled and added as todos so I “just” needed to tackle of the tasks, one by one. Every week.

For everyone writing a book, here are the actual tools I used:

  • Evernote: Write the Outline for the book and chapters
  • Google Docs: A document for every Chapter where I could write each day
  • Word: Put all Google Docs chapters together into the final book

While there might be better writing tools like iBooks Author for Mac I was fine with those tools. Everything works as long as you get the job done.

Once everything was ready I only had to put the different docs into one Word document, add stuff like a cover and table of contents and I was almost done. At this point I used a service called Fiverr to get stuff like the cover done. If you have simple tasks you can outsource, do it.

Finally the book was reviewed by some friends. Although this was awesome (thanks again so much) I probably could have given out some copies to other bloggers or readers to get a feedback on that version. Maybe next time.

Even while writing the book, there is another thread you need to follow and that’s the marketing side. Although many of you might not like the word at all, marketing is what actually amplifies your voice and message to reach more people. That’s why you need some kind of marketing strategy for launching any product!

Building up a Buzz

If you can build up a buzz for your product even before launch, you will have a good time.

The first step for Ionic 2 – From Zero to App Store was the pre-launch of an at that time not yet finished product.

This gave me not only the confidence that the book would be relevant for people but also created a first group of people who were just waiting for the release of the book.

After this first pre-sales I regularly spoke about the book on Twitter, my Email list or Instagram to keep people interested and engaged.

The plan was to give out all needed information about the book and packages before the launch, so people would (hopefully) already line up and wait for the release.

On the release date I only had to announce that “it’s available now” and people had all the information they needed upfront.

To most parts, this worked really great. If you were on of the buyers or in that group of people, I would love to hear from you if you would have needed anything else before the launch, like more progress, more insights into the book and stuff like that.

The pre-sale was 19$ at the first stage and moved to 29$ after the very early phase which turned out to be the final price of the lowest package at launch.

A Word on Pricing

The book comes in 3 different packages. Why?

People at different levels have different needs. And the packages are there to give additional value to those who want it.

The 3 packages are:

  • Basic Package (29$) – Only the eBook including code for all examples
  • Advanced Package (49$) – The eBook plus a dummy app showing a login and a submission checklist to release your app in a more structured way
  • Ultimate Package (79$) – Everything from before plus a real App + Node.JS server for user authentication and an HTML template to launch your app and promote it

These packages served different needs, and by now the prediction of most guides comes through. Although the basic package has the most sales, the ultimate package is bringing in the most money from those 3.

Whenever you have the chance to add additional value to your product, go for it. Don’t just throw in a bunch of useless stuff, but think about what people purchasing your product might actually need, what could help them after finishing/using your product?

It’s about offering value, not just having packages for the sake of packages to earn more money.

Releasing the eBook

Before the book was finally released, many emails were sent out. Especially in the week before the final date, I announced everything important about the book, the packages, what you will get and which package would be for whom.

The launch period was 2 days long and started with the email that all packages are now available. For 2 days, people could get both higher priced packages for a discounted price.

Like always with a launch, you will see a spike of sales in the beginning and a spike if you announce that the discount ends soon.

ebook-sales-spikes

Make sure to plan in time for those days, because things will go wrong.

People will have questions and problems.

Offer support whenever possible and wherever needed to help your customers along their shopping journey.

Finally, expect hate.

Why?

Let’s say you miss black friday and go to the shop the week after and you rage about why you should pay the regular prices.

Sounds strange?

Well, exactly that happened. After the discount of the launch ended, many people emailed me they would see a higher price. Well, yes this is what happens when a discounts ends.

Some of them were not really polite, but you have to stick to your word. Even if you miss out on 1-2 sales, it’s not worth to look like your word doesn’t mean anything!

So a launch is always a mix of fear and happiness, but if you prepare well and manage everything the happiness should be the much bigger factor here.

Automating & Marketing

After your launch you can play around with automation and different sales funnels.

Never heard of that before?

Easy example: You can get my 7 day Ionic 2 email course, and at the end there will be a little pitch for my Ionic 2 book. This is a sales funnel.

They are automated emails, send out on a schedule and leading the subscriber finally to a product of mine. Again, it’s not only about making the sale, it’s also offering the subscriber a solution to his problem (learning Ionic 2) and giving them the chance to get even deeper material after this 1 week course.

To push your sales you can also start guest posting around like I did on the official Ionic blog, you can try to get more influencers on board to speak about your book or start an affiliate program where others get paid if people buy through a special link.

There are many options and routes, and there is no one-fits-all solution so experiment and mix, throw some stuff at the wall and see what sticks!

Conclusion

Writing a book was hard work, especially if you do it next to your full-time job. Every morning I would get up an hour earlier to write another chapter. And steadily you achieve something that you previously thought would never be possible.

Make sure to give yourself deadlines, establish a plan from that date and tackle off small tasks, every week, every day.

Was it worth?

From the financial side it was ok, but from the experience side it was even better. Every project helps you to learn, grow and become more confident in what you do.

Finally, the value generated for the subscribers and readers of Devdactic is what counts in the end.

If I was able to help one single person to build and release an Ionic 2 app my goal is reached.

Happy Coding,
Simon

The post Behind the Scenes of Launching an Ionic 2 eBook appeared first on Devdactic.

Ionic 2 Push Notifications In Detail

$
0
0

The topic of Ionic 2 Push Notifications was requested many times on my original guide to Push Notifications with Ionic 1, and maybe even the most asked about feature right after user authentication.

In fact it’s not that hard at all to get it working with Ionic 2, the only problems that can arise are those coming from the certificate hell of iOS (and sometimes Android). Let’s se how we can get real Ionic 2 Push Notifications inside our hybrid app!

iOS Certificate Setup

The Ionic team offers a very detailed guide on how to create the profiles you need, so I recommend you stick completely to this documentation on iOS Push Profiles.

Also, to generate these certificates you need a Mac and also need to be part of the Apple Developer Program. If you just joined now, you might also need to set up your general iOS Build Profiles, but you don’t need this step if you have already previously created iOS apps.

After going through the Push guide you need to have your App Id from the Identifier you created inside your Apple profile. Copy that ID and open your config.xml and add your ID:

<widget id="YOU_APP_ID" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">

This is important because now your build iOS app will also have that bundle ID, which it needs to receive our pushes.

The last thing for iOS you need now is to upload the needed certificate into your Ionic.io security profile. You might have already done this as a final step of the Ionic guide, so just make sure that inside your security profile the Push Notification Service is set up correctly like this:
ios-security-profile

Android Setup

The setup for Android is even a bit easier, because the certificate-signing-provisioning stuff get’s a lot easier. For Android you need to be inside the Google Developers program, and you also need to set up some basic keys (if you have never created Android apps before) using this documentation from Ionic to sign your apps.

If you have already worked with Android apps before you can skip that step.

The next step is to create a Google API project inside your dashboard and enabling Google Cloud Messaging. As I can’t describe it any better, please follow the advise on Android Push Profiles from Ionic.

After going through this steps you should have already added the API Key to your Ionic.io security profile (if not do now) and the result should look like this:
android-security-profile

Ionic 2 App Settings

After going through all of this, the rest becomes pretty easy. For testing I started with a blank new app and installed the by calling:

ionic start --v2 myApp blank

After our app is ready (or just inside your folder if you already have an app) we need to install two things:

Keep your FCM Sender ID near because this is needed when adding the Cordova platform! Go ahead and run:

npm install @ionic/cloud-angular --save
cordova plugin add phonegap-plugin-push --variable SENDER_ID=12341234 --save

Make sure to put in your real sender id in that command of course.

Finally, we need to make our app available to Ionic Cloud. If you haven’t done before inside your app, simply run:

ionic io init

If you have no account you might need to create one first. The basic account is still free, so create one in order to sen out easy Ionic 2 Push Notifications.

Inside our app we need to configure our cloud connection as well. We need to set the id of our app (which we got back after calling the last init command, or which can be found inside your dashboard) and the FCM id again. Open the src/app/app.module.ts and insert:

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { CloudSettings, CloudModule } from '@ionic/cloud-angular';

const cloudSettings: CloudSettings = {
  'core': {
    'app_id': 'your-ionic-cloud-app-id'
  },
  'push': {
    'sender_id': 'your-android-FCM-id',
    'pluginConfig': {
      'ios': {
        'badge': true,
        'sound': true
      },
      'android': {
        'iconColor': '#ff0000'
      }
    }
  }
};

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

After creating these settings, we need to tell our app to use them. Therefore we add the cloudSettings to our array of imports and load them for the CloudModule inside our module declarations.

The last step is to react on incoming push notifications. We can specify this behaviour wherever we want, but we need to make sure the platform is ready and all Cordova plugins are loaded.

In this case I used the first created component which is the entry point to our app anyway, so open the src/app/app.component.ts and insert:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

import { HomePage } from '../pages/home/home';
import {
  Push,
  PushToken
} from '@ionic/cloud-angular';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = HomePage;

  constructor(platform: Platform, public push: Push) {
    platform.ready().then(() => {
      StatusBar.styleDefault();
      Splashscreen.hide();

      this.push.register().then((t: PushToken) => {
        return this.push.saveToken(t);
      }).then((t: PushToken) => {
        console.log('Token saved:', t.token);
      });

      this.push.rx.notification()
      .subscribe((msg) => {
        console.log('I received awesome push: ' + msg);
      });
    });
  }
}

You can do a lot more here, but the important part is to call register() so Ionic.io knows about your device. If you run this on a device, you should see your Push token inside the log. That is a good sign!

We also want to log incoming Push Notifications if the app is open, because otherwise you wouldn’t actually see them sometimes. If you app is closed you will of course see a banner at the top (unless you send silent pushes).

Make sure you can definitely see the successful log of the registration before trying the next steps!

Note:
For iOS you will most certainly have a newer version of Xcode, therefore you need to enable the Push Notifications entitlements inside your project. Like in the image below, open the project settings with Xcode and navigate to Capabilities and switch it to on. Also, if you want to use silent background notifications at some point, enable “Remote notifications” like in the image.
push-xcode-entitlements

Sending out Push Notifications with Ionic Cloud

Make sure that you only launch your app on a real device from now on if you want to test Push Notifications. All of the following won’t work inside the browser!

So once you have started your app, you should see your Push token in the log which means you are subscribed to receive Push notifications. We are currently not segmenting our users, as we haven’t used the authentication features of Ionic Cloud. If you want to send more targeted Push notifications, you would need to integrate the authentication of Ionic cloud as well.

Anyway, we want to see Push in action so open the Dashboard of your app inside the Ionic Cloud, navigate to Push and click “Create New Push”.

ionic-cloud-dashboard-push

Inside the new dialog you can now specify all kind of information for your push like title, the actual message, a payload or even device specific options.

Add whatever you like to and hit continue to get to the next step.

ionic-2-push-create

The next page allows to specify which users should get the Push, but as said before we are not using the authentication feature so we can’t select between different users by now. Leave the settings to “All users” and hit continue again.

Finally, you can select when the message will be sent and also which profile to use. Make sure to select the one you created in the beginning and then fire the railsguns!
ionic-2-push-fire

It may take some time, but finally you should be able to see your notification appearing on your device like below:

ionic-2-ios-push-received

Conclusion

That’s it! You managed to create all the needed profiles and connected everything through the Ionic Cloud platform. If you need more targeted notifications, you could add the authentication mechanism. If you would like to see more on integrating the authentication, just leave a comment below!

Otherwise, you can also create a Push without the web interface by using the REST API. In that case as well leave a message if you want to see how it’s done.

Happy Coding,
Simon

The post Ionic 2 Push Notifications In Detail appeared first on Devdactic.

Preview of the Ionic Academy

$
0
0

Let’s face the truth: Learning to code is challenging and can sometimes be frustrating. You can get lost in your self studies and reach a point where you loose interest and focus on something else because you simply can’t find anymore fun in it.

The Ionic Academy aims to to break that pattern and help you to learn to build mobile apps using the Ionic Framework in a more comfort environment.

While the internet is full of information, you sometimes still don’t find what you are looking for. Although many others are learning the same language you can feel alone from time to time.

That’s why the Ionic Academy consists of the following (current) building blocks.

Step by Step Courses

First of all you need to get information about concepts. How are things actually working in a specific language? What does the code look like? What is the meaning of this and that (no JavaScript pun intended)?

To describe and present different topics the Ionic Academy has Courses, most of them being a mix of screen recordings, presentations and sometimes written material.

Instead of being overly long sessions where you find it hard to follow, those videos will very rarely be over 7-8 minutes. Because of these shorter videos it’s more easy for you to follow along, quickly complete a session and still keep in mind what you actually learned in the video.

The library of courses will be divided into 3 categories, depending on where you currently are in your learning curve:

  • Beginner
  • Intermediate
  • Advanced

You can start with courses you feel comfortable with and work your way up through the material. All your progress is tracked and you can jump back to where you left off, bookmark your special sections and watch them later again!

academy-preview-courses

Initially the library will consist of different starting courses for all 3 categories which means everyone can start where he is. This library is by no means complete and will grow more and more over time.

After your great initial feedback (thank you so much again!) there is a quite long list of possible future topics to present, and there will be polls about which course to create next so you can actually vote and raise your voice what you think would be useful. Still, this is a democratic process so sometimes you might be in the minority, but the next time your preferred might be selected!

Hands On Projects

The first part of learning was to see something new, the following part is of the same importance if not even higher.

You need to use what you have learned!

This part of learning something new is unbelievable valuable and helps you to actually keep the knowledge you have gathered. If you don’t transfer what you have seen/read into action there is a high chance of forgetting everything quite fast again.

Just think about this: You read an 200 pages instruction handbook for something without actually touching the system meanwhile. Do you think you will still now the stuff you read on page 42 after completing the book? Very unlikely.

Therefore, most courses inside the Ionic Academy library have a hands on project at the end where you are presented with a tiny challenge that you have to implement. This challenge is based on the prior course and helps you to take action on the material.

academy-preview-projects

These projects are just like the courses divided into the 3 stages of your knowledge.

Of course you can also just go though them separately if you want to, but it makes more sense to complete them at the right spot after the courses to save your learnings inside your head!

Just like the courses, the initial amount of projects is by no means the final amount. There will be updates and new projects just like there will be new courses from time to time.

Helpful Community

After learning some material, applying the knowledge by creating your own little projects you might still feel a bit lonely in your learning journey.

That’s where the community comes into play!

The Ionic Academy has a forum so you don’t feel alone with your problems and questions. There will be helpful people around you which all have the same goal: Learning and building great mobile apps!

If you encounter problems with the courses and projects, this is the place to ask your questions. If you are developing your own app using Ionic, you will find friendly and open feedback inside the forum.

academy-preview-community

Even if you have finished most of the courses or projects, there is still something new to explore on the forum.

How to become a Member

The Ionic Academy will be a membership site with a monthly fee with the option to be paid yearly. While all the material on this blog was and still is free, the Academy offers in depth training and support on a deeper level.

The connection between courses, projects and the community crafts a friendly environment for everyone interested in learning Ionic.

Of course many of you might be still at a student level or living on a small salary, therefore the monthly fee will be small enough for everyone to join the Ionic Academy. And this means about the price of one good lunch!

Investing in your career is one of the best things you can do as a software developer.

Outlook

The first opening of the Ionic Academy is near, so make sure you get on the early bird list to get notified once we are live.

This will be the first opening and of course the library of material will grow over time, and it will be very much influenced by the people who are inside the Academy!

Happy Coding,
Simon

The post Preview of the Ionic Academy appeared first on Devdactic.


Automatic Ionic 2 Builds For iOS Using Fastlane

$
0
0

When your project get’s close to release, it’s time to think about decent ways to build your Ionic app. Of course you can do this by hand, but if you are having multiple apps and configurations this can get out of hand very fast. Also, the iOS upload process takes time – which you actually don’t need to spend!

In this post I will show you how you can automate your Ionic builds for iOS (later maybe Android as well) using the famous Fastlane tool. We will integrate the script and achieve automatic build & upload to iTunes connect Testflight. As a little bonus we will also post to a Slack channel!

In fact there are many configuration files you have to prepare, but don’t be scared. Once you got all of them for your project setup, you can build & upload your apps with one command!

That worth it, isn’t it?

If you want all of the created files of this article in one package, simply insert your email below.

What is Fastlane

Fastlane Github
Over time, Fastlane has developed into the tool to release iOS and now even Android apps. Fastlane is made up of different modules where each covers one specific aspect of the distribution process of your app.

The Ionic build leaves you with a native project, but most developers coming to Ionic might not really be familiar with Xcode or how to submit your apps.

Fastlane can be used to create your app entry using the command line, to create the profiles and certificates for your app, to build and upload a correctly signed package and to do many more things which can’t be all covered right here.

Whether you are using a Continuous Integration server like Jenkins or just want to be able to upload your iOS apps with one click, Fastlane can save you a lot of time over the lifetime of your app.

As they say it’s “The easiest way to automate building and releasing your iOS and Android apps“.

And that is really true.

Setting up everything we need

To get started with Fastlane you need to install and configure some dependencies. First of all we need to install Fastlane using Ruby. If you are on a Mac you can update Ruby using Homebrew, if you are not on a Mac or not using Homebrew make sure to have Ruby installed and up to date.

Once this is done you can install the “gem” (the name for Ruby packages) by running:

sudo gem install fastlane -NV
gem install bundler

We also install Bundler which helps us to install the right ruby packages inside our environment.

As said before, Fastlane consists of different modules and we are using a special module called Match to handle all certificate creation and signing for us.
Match will dramatically simplify the iOS code signing process for you. The idea is that all certificates and profiles will be stored in a separate Git repository.

By doing this, everyone from your team has access to the right profiles and can build the apps without any problems. But you need to have a Git repository in place for Match!

The easiest way is to create a private repository on either Github (paid account) or on Bitbucket (free account).

So make sure to have the repository URL at hand once we configure our match settings later!

Bonus: Slack integration

If you like fancy things, you can let Fastlane directly post to your Slack channel!

If you can manage your Slack team, the setup is quite simple. Simply go to the website of your channel and manage plugins.

From there, add an Incoming Webhook like in the image below.

slack-incoming-webhook

Inside the configuration you can add the channel where Fastlane will post, and finally make sure to copy the Webhook URL as this is the URL Fastlane needs later.

Configure Basic Fastlane Settings

Ok, until now we actually haven’t done anything special with Fastlane so let’s change that.

Inside your Ionic 2 project, create a folder called “automatic-build“. Inside that folder we will keep everything related for our build process. First of all, we add simple bootstrap file to init everything we need, so create a bootstrap.sh with the content:

gem install fastlane-plugin-update_project_codesigning -v 0.2
bundle package
echo "Fastlane setup finished!"

Execute that file and you have the plugin we need to update our Xcode settings installed.

Next to that file we create a environment file which will hold some general information for Fastlane. Create a “.env” file and insert:

CUSTOM_APP_NAME="YOURAPPNAME" # Your App Name (like in config.xml)
CUSTOM_APP_ID="com.xyz.name" # Your bundle ID
CUSTOM_TEAM_ID="123456789" # Your iOS Developer Team Id
SLACK_URL="https://hooks.slack.com/services/...." # Your Slack Webhook URL
FL_PROJECT_SIGNING_FORCE_UPGRADE = "true" # Just add it, needed to automatically do everything.

Now, next to the stuff created before, we create another folder called fastlane which needs a few files:

  • Appfile – Holds information about our App and Developer Account
  • Gymfile – Information for building the native iOS project
  • Matchfile – Retrieve the profiles from the Git repo
  • Fastfile – The file with the actual Fastlane tasks

This might seem like a lot of configuration, and you are absolutely right. But once you have everything configured and run your automatic build the first time, you will know everything was worth the effort!

Make sure to replace the dummy values in some of the files with your own values.

We start with the Appfile which holds some general information about our app:

app_identifier "com.xyz.yourname" # The bundle identifier of your app
apple_id "your.name@gmail.com" # Your Apple ID Email address
team_id "12345678"  # Developer Portal Team ID
itc_team_id "12345678" # Your iTunes Connect Team ID

Next, the Gymfile has the information to the path of our Xcode project, as we are not in a native iOS project but still in an Ionic project (you almost forget that, right?). So here we “cheat” some paths for Fastlane so it finds all the needed files & folders:

scheme "YourName" # Scheme of your native app, just the Name from config.xml
project "../platforms/ios/YourName.xcodeproj" # Should be the path to the iOS project
output_directory "./build" # Where the app will be build to
output_name "MyApp" # Final output for the IPA

Next the Matchfile, this file has the information for your repository where all your signing certificates will be kept:

git_url "git@bitbucket.org:yourrepo.git" # Repository for Match
type "appstore"

Finally, the Fastfile is the most important file as it does the actual work. In this file you can specify “lanes” which you can than run via Fastlane. For now, we just add the minimum and add the 2 lanes in the following steps:

# This is the minimum version number required.
# Update this, if you use features of a newer version
fastlane_version "2.11.0"
require 'xcodeproj'

default_platform :ios

platform :ios do

# Put in Lanes here!

end

Alright, if you got to this point I can promise that things will get easier now. We are done configuring everything and can get to work.

Creating a new iOS App with Fastlane

If you have ever released an iOS app you now the process can get out of hand a bit. You need to create various ID’s and profiles everywhere, and if you don’t know what you are doing you get lost soon.

Lucky us, we can now rely on Fastlane to handle the hard part of the app creation!

If you have added all the needed information before, just add this lane to your Fastfile where you currently have the comment and replace the values inside the lane with your own:

lane :newApp do
    produce(
        username: 'my.email@gmail.com', # Your iTunes ID
        app_identifier: 'YOUR.BUNDLE.ID', # Your App Bundle ID
        app_name: 'MyApp', # Your App Name
        language: 'English',
        app_version: '1.0',
        sku: '123',
        team_name: 'Your Name' # only necessary when in multiple teams
      )

    # Post to Slack
    slack(
      message: "Created new App!"
    )
  end

To run this lane, simply call:

fastlane newApp

You might get asked for some passwords here, so enter them and your app with all the needed certificates on the Developer Portal (including the iTunes Connect entry!) will be created.

If you hit any problems at this point, you can of course also setup everything by hand just like you normally do.

Configuring our Fastlane Build

Alright, all of this before only needs to be setup once, now it’s time to prepare our actual app to be compiled and build with Fastlane.

Make sure all your variables are setup correct and especially your bundle ID inside your config.xml matches the one you have specified inside the Fastlane files.

Our next Lane will do everything from building the native iOS project, downloading signing certificates, changing entries in the project, creating the IPA file and uploading to iTunes Connect.

All of that can take you a lot of time, so again, this is really worth it.

Open your Fastfile and add this Lane:

desc "Submit a new Beta Build to Apple TestFlight"
  lane :beta do    
    # Fetch and Create Profiles
    match

    # Retrieve App Name and ID from environment
    name = ENV['CUSTOM_APP_NAME']
    app_id = ENV['CUSTOM_APP_ID']
    team_id = ENV['CUSTOM_TEAM_ID']

    xcodeprojpath = "../platforms/ios/" + name + ".xcodeproj"

    # Update Code Signing
    update_project_codesigning(path: xcodeprojpath, use_automatic_signing: false, team_id: team_id)

    # Patch Project Settings
    proj = Xcodeproj::Project.open("../" + xcodeprojpath)
    
    proj.build_configurations.each do |item|
        item.build_settings['DEVELOPMENT_TEAM'] = team_id
        item.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "iPhone Developer"
        item.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = "match AppStore " + app_id
    end

    proj.recreate_user_schemes
    proj.save
    # End of Patching Project Settings

    increment_build_number({
      build_number: latest_testflight_build_number + 1,
      xcodeproj: xcodeprojpath
    })
    
    # Build the IPA
    gym

    # Upload the IPA to Testflight
    testflight(
       skip_waiting_for_build_processing: true, 
       ipa: "./build/MyApp.ipa"
    )

    # Post to Slack
    slack(
      message: "Successfully Upload " + name + " to ITC Testflight",
      default_payloads: [:git_branch, :last_git_commit_message]
    )
  end

Make sure to replace values with your own where needed, and then you are ready to go for it big time.

Build & Upload your App

Finally, I like to have one file to invoke everything. Therefore, we go back to the root of our Ionic 2 project and create a buildIOs.sh with the following content:

ionic build ios
cd automatic-build
fastlane beta

This script will first of all build the ionic project so we got our native iOS project and then switch to our automatic-build folder and do the Fastlane magic!

Again, you might be asked for keys here & there in the beginning but after adding them once Fastlane should work without any further attention.

Fastlane will now build, sign and upload your app which can take 5-10 minutes depending on size, speed of connection and the Apple servers.

Brew some good coffee and let fast lane do your job until it’s finished!

fastlane-upload-finished

Start Testing your iOS App

Once Fastlane is finished (you might have a notification in your Slack channel!) Apple takes some minutes to process the build. You will also receive an Email once that is finished.

If you now login to iTunes Connect and switch to the TestFlight tab, you can see the uploaded version and select it for testing.

Add you testers, start the testing and enjoy your new freedom and saved time!

Conclusion

You might have to tweak the process and files here and there, change some credentials or install needed dependencies but overall it will work in the end and you will save a lot of time, especially if integrated with a CI environment like Jenkins!

The setup with Fastlane is also possible for Android, so in case you are interested let me know and I’ll try to work out the Android automatic build as well.

Happy Coding,
Simon

The post Automatic Ionic 2 Builds For iOS Using Fastlane appeared first on Devdactic.

Protecting Your App With Ionic Auth Guards

$
0
0

Recently I dig into authentication with Ionic a bit more and found a rather unrepresented topic that can actually help to secure your app really easy. I stumbled upon the Ionic Auth Guards while working on a new JWT Authentication course for the Ionic Academy.

The Ionic Auth Guards are the Ionic version of the Angular Navigation Guards. The guys from Thoughtram have a great post on this topic as well.

But Angular uses a different kind of routing (more of the classic URL routing style) than Ionic, which uses a simplified routing system targeted more towards mobile and the logic of different pages and viewcontroller.

Therefore we can not use the original Angular Navigation Guards but the Ionic version, which we will explore in this post.

The Logic

Ionic pages have different lifecycle events. If you want a complete overview about all events and the order in which they pop up, check out this post from Sani Yusuf which has a very good image of it as well.

The Ionic Auth Guards fall right into that category of lifecycle events and are called ionViewCanEnter and ionViewCanLeave and both will do exactly what they sound like: Either allowing navigation to a page or navigation away from a page. In detail these events are a good place to do the following:

ionViewCanEnter()

This event is fired before a page is loaded. No action of the page has taken place by now, and you can determine if the page is allowed to be presented. This means, you could check some conditions or in our case the authentication state of a user. If this function returns false, we need to make sure we handle this correctly as we normally assume every page will be pushed/displayed just fine.

ionViewCanLeave()

This is the counterpart to the before mentioned event and is fired right before a page tries to leave the screen. I thought about the usefulness of this event a bit more as in general you don’t want to forbid your user to leave a page! But in cases like inside a form where something needs to be filled out, catching the state of the form inside here could make sense. Anyway, you don’t want to completely forbid your user to leave a page, otherwise they will simply kill the app if they have “no way out”.

One note for authentication systems: Of course protecting pages is only one part of building authentication, you also have to take care of the backend logic of logging a user in and afterwards making authorized requests for example by sending an authorization header with your requests.

However, in our little example we will leave out the backend component and just fake it with a service that holds our current authentication state of the user.

Simple Auth Guard Example

As always, we start with a blank Ionic app. Additional we create a second page where we can navigate to, and also a provider which works as the manager for our user authentication state:

ionic start --v2 authGuardApp blank
cd authGuardApp
ionic g page Second
ionic g provider AuthService

First of all, make sure to add the new page and the provider to our module, so open the src/app.module.ts and insert:

import { AuthService } from './../providers/auth-service';
import { SecondPage } from './../pages/second/second';
import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';

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

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

As said before, our AuthService is just a dummy implementation without a real backend. However, we can represent the general behaviour of a regular auth service quite easily, and you could use this provider as a base for your own implementation.

Go ahead and insert into our src/providers/auth-service.ts:

import { Injectable } from '@angular/core';

@Injectable()
export class AuthService {

  private isLoggedIn = false;

  constructor() {}

  // Login a user
  // Normally make a server request and store
  // e.g. the auth token
  login() : void {
    this.isLoggedIn = true;
  }

  // Logout a user, destroy token and remove
  // every information related to a user
  logout() : void {
    this.isLoggedIn = false;
  }

  // Returns whether the user is currently authenticated
  // Could check if current token is still valid
  authenticated() : boolean {
    return this.isLoggedIn;
  }
}

We got everything we need for now, let’s use these functions.

We only need a very simple view for this example, just a few buttons and a title that indicates whether we are currently logged in.

Therefore, open the src/pages/home/home.html and insert:

<ion-header>
  <ion-navbar>
    <ion-title>
      Auth App
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
<h2 *ngIf="isAuthenticated()" text-center>User is logged in!</h2>
<h2 *ngIf="!isAuthenticated()" text-center>User is not logged in!</h2>

<button full ion-button color="primary" (click)="loginUser()">Login</button>
<button full ion-button color="danger" (click)="logoutUser()">Logout</button>
<button full ion-button color="secondary" (click)="nextPage()">Next Page</button>

</ion-content>

Nothing special so far, next the page with the functions. We need to hook up the actions to login and logout our user. We can simply do it through our authentication service, which is always a good way to do such a task.

Also, the state of the current user is only managed within that provider so we only need to look for changes there.

Finally, the function to push our next page is what more or less everything before was about. Instead of simply pushing a page onto our stack, we catch the possible error event and display an alert when it happens.

No additional check has to be made here, the rest is up to the following page to decide wheter someone can enter! Therefore, open the src/pages/home/home.ts and insert:

import { SecondPage } from './../second/second';
import { AuthService } from './../../providers/auth-service';
import { Component } from '@angular/core';

import { NavController, AlertController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController, public authService: AuthService, public alertCtrl: AlertController) { }

  loginUser() {
    this.authService.login();
  }

  logoutUser() {
    this.authService.logout();
  }

  nextPage() {
    this.navCtrl.push(SecondPage).catch(err => {
      let alert = this.alertCtrl.create({
        title: 'No entry!',
        subTitle: 'You shall not pass',
        buttons: ['Okay']
      });
      alert.present();
    });
  }

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

As said before, the last part is now up to the following page. Inside that page, we implement the ionViewCanEnter to prevent someone getting to this page if they are not authenticated.

In our case, the only check we need to perform is calling our authService again to see if a user is authenticated.

Overall you could also check for a token inside the storage and even return a promise inside this function, as the page transition event will wait for this function to finish!

It’s a really good place to check your authentication state, so open your src/pages/second/second.ts and insert:

import { AuthService } from './../../providers/auth-service';
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

@Component({
  selector: 'page-second',
  templateUrl: 'second.html'
})
export class SecondPage {

  constructor(public navCtrl: NavController, public authService: AuthService) {}

  ionViewCanEnter() {
    return this.authService.authenticated();
  }
}

Now go ahead and play around with our easy Ionic Auth Guard example and work in your own backend calls and authentication logic inside the authService!

What next?

Of course this is only a basic example showing whats possible. The function to check our validation state should do a bit more depending on your system and probably return a promise.

If you want to use ionViewCanLeave is up to you, for some protected pages the ionViewCanEnter offers everything we need!

You can find a video version of this post below.

Happy Coding,
Simon

The post Protecting Your App With Ionic Auth Guards appeared first on Devdactic.

Building an Ionic Image Gallery With Zoom

$
0
0

The image gallery is a classic pattern used in many applications which need to display any kind of grid with pictures or photos to the user. If you have specific requirements, there might not be an out of the box solution that works fine for you, that’s why we will create our own Ionic image gallery.

We will display images in a gallery like infinite loop where we can always see the end of the previous image and the start of the following. This question came up inside the Ionic Academy and the solution we found should do the trick. Additional we make use of the Ionic-img-viewer component which helps us to display a selected picture in fullscreen with zooming options.

I tried to implement zooming on my own, but at the time writing this article (v3.0.1) the ion-scroll property for zooming does not really work. Hopefully in the future we will be able to use that zoom to build our own zooming view!

Setting up our Image Gallery App

For the start we need only a blank Ionic app and install already the npm package for our image preview, so go ahead and run:

ionic start --v2 ImageGallery blank
cd ImageGallery
npm install --save ionic-img-viewer

Before we do the rest of our work, we need to connect everything inside our src/app/app.module.ts to load the module we have just installed:

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

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

import { IonicImageViewerModule } from 'ionic-img-viewer';

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

Very basic, nothing really special at this time!

Building our Image Gallery

If you want to display some images, make sure to add some to your project. In my case I copied 4 images to the src/assets/img folder, named “1.jpg” and so on.

To load these images we create a very simple array inside our page, so go ahead and add it to the src/pages/home/home.ts:

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

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  images = ['1.jpg', '2.jpg', '3.jpg', '4.jpg'];

  constructor(public navCtrl: NavController) {

  }
}

Next the actual view for the image gallery. We can make use of the ion-slides component, which is normally displaying full pages of content where you can swipe through.

However, with some properties and CSS we can finally achieve the desired look for our gallery!

Also, this component is based on the official Swiper component, where you can find many examples for animation of this component, including different effects and how the properties change the behaviour.

Almost all of these work with the Ionic component as well, so if you want some cool effects for example try adding effect="coverflow" for a nice coverflow effect with your Ionic slides!

Back to our view, we loop through our images, create the slides and display the according image in each of them. There we also add the imageViewer property which will take care of the click event on an image and display the special image viewer!

Now go ahead and insert to your src/pagges/home/home.html:

<ion-header>
  <ion-navbar>
    <ion-title>Image Gallery</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-slides class="image-slider" loop="true" slidesPerView="2">
    <ion-slide *ngFor="let img of images">
      <img src="assets/img/{{img}}" class="thumb-img" imageViewer/>
    </ion-slide>
  </ion-slides>
</ion-content>

As said before this is not yet the desired outcome, therefore we need to apply a tiny CSS tweak and make it look a bit better as well. Put the code below into the src/pages/home/home.scss:

page-home {

    ion-slide.swiper-slide {
        left: 25%;
    }
    
    .slide-zoom {
        background: #e6e6e6;
    }

    .thumb-img {
        padding: 10px;
    }
}

Now your image slider should do exactly as we want, and the result will look like the images below. First, the gallery inside your view:

By using 2 slides per view but adding the distance to the left and setting the size of each slide to only 50% we were able to craft this tricky view.

If you now select one image, the image viewer component comes up where you can zoom in and swipe down to leave the view (or use the button at the top):

Conclusion

It actually don’t takes a lot of code to build a gallery, but if you want it in a special way you might have to tinker around with some CSS that works for you. Also, using an external module for the zooming view is not really perfect (although many thanks to Riron for creating it!), but hopefully this will be fixed in an upcoming Ionic release.

For now enjoy your Ionic image gallery with zooming functions!

You can watch the video version of this article below.

Happy Coding,
Simon

The post Building an Ionic Image Gallery With Zoom appeared first on Devdactic.

Why I Switched to Ionic (And Never Regret My Decision)

$
0
0

It’s not like native development is bad. Swift itself is a beautiful language, and even Android Studio is not that bad anymore, so how comes more and more people transition to Ionic?

This article reveals some reasons about switching to Ionic and why I never looked back since. Not all of these have to appeal to you, but for me everything together made the difference.

A Tiny Decision

devdactic-first-ionic-post
Almost 2,5 years ago this blog was created, and though I did not know where it would take me I picked up the Ionic Framework as a cool new way to build better cross platform apps. Better than all the frameworks like Titanium before. More beautiful than just Cordova.

At first, coming from a native iOS background everything else that helped to also build Android apps looked interesting. AngularJS was completely new to me, but as I began to pick it up I found it to be quite powerful and somehow we fell in love.

After this rather random encounter I kept blogging about Ionic for whatever reason. It just felt good to develop Ionic apps back then!

Today, this blog has grown to a platform with advanced help for all Ionic developers like the Ionic Academy.

Many people still struggle to decide between frameworks like NativeScript, React Native, Xamarin or Cordova. This post ist not a comparison, and if you think the air smells better to your left, pick that path like Gandalf. I’m not here to tell you which is the best framework (because honestly, there is no single best).

I’ll give you my point of view about why I switched completely to Ionic, and if you feel the same why I never looked back since.

Ionic in Action

If you are new to Ionic, it’s kinda hard to wrap everything it makes up into a few sentences. I’ll put the Github message here for simplicity:

Ionic is the open-source mobile app development framework that makes it easy to build top quality native and progressive web apps with web technologies. – Ionic Github

ionic-logo-horizontal-transparent

At it’s core, Ionic is a NPM package which will give you beautiful styled components inside your App, which will look and feel native on both iOS and Android. And there’s also the API you can access directly through Angular (at the time of writing Angular 4). And then there is Cordova.

Cordova is a project on its own, but it’s used inside the Ionic project to add plugins, which are the bridge in your app to native plugins like the camera. Or to finally build your app into a native project, where your web code will run inside a web container.

Oh, and Ionic also has an own wrapper around these Cordova plugins to make your life easier.

And then there are more built in solutions for theming your app, for saving data inside the local storage and and and…

And finally the Ionic Cloud, a cloud platform with more services to easily connect to your app.

You see, it’s quite hard to get all the components of Ionic first, that’s why it is more a complete Ecosystem.

And it’s a living ecosystem!

The Community

The Ionic community is very open and helpful, be it inside the Slack channel, the students of the Ionic Academy or anywhere else on Quora or SO.

academy-logo-dark

Max Lynch, Co-founder of Ionic does a great job of always keeping an eye on the overall mission. If you want to get deeper insights and thoughts about Ionic, make sure to check out his Medium profile and the articles of the last year.

With any rather “new” framework, you sometimes have problems finding help. Not with Ionic.

First, there are already countless tutorials, courses, books and everything you need out there because the number of people using Ionic is growing heavily over the last years.

Second, at its core it’s still Angular, so everyone using Angular can and will be helpful for your problems as well!

Finding help and support for your problems is a major point inside the equation and comparison to other frameworks. But like all other frameworks, new versions will come and you might find yourself at the front line more often than you like..

The Progress

The progress of Ionic and everything inside its ecosystem is sometimes astonishing to me. And at the same time scary.

As a creator of content, I sometimes can’t keep up with the pace to update code which is now already outdated again. And this is not a personal problem, but at the same time a problem for people looking for help.

People find outdated code, sometimes not even knowing it is deprecated. Some updates brake the process of your CLI and you don’t know why suddenly everything stops working.

I guess this is the normal pain that comes with faster progress.

Ionic 2 was and still is a major milestone for cross platform app development, and all further versions will improve and contribute to that experience. Through Angular 2 and TypeScript people get a sense what it means to write modern JavaScript.

The good thing here is the progress is made not only on the code side (which sometimes drives us mad) but also on the technology side of the Ionic services.

With Ionic Cloud, developers get powerful tools directly in one place, and products like the Ionic View App or the Creator are just 2 great examples of the strategic minds behind Ionic.

The Ionic team experiments with different options and is also able to cut off projects that tend to end up not useful for mobile developers early enough.

The Future

For some months Ionic tried to develop something similar to Firebase called Ionic DB. Although the idea was appealing, they decided very early to end the project because it would be a hard sell. There are already great alternatives out there, and people would need to make a decision to leave their current DB provider and migrate to Ionic.

So although they are making progress in many areas and bringing new ideas into the game, they are also able to cut off what’s not working.

Currently you can see the fast progress with Ionic 3 already being released, just a few months after we saw the final release of Ionic 2.

They stick their development now close to the Angular releases, that’s why we will see more and more major version upgrades over the next years.

In terms of other new technologies we should mention the PWA support out of the box, something Ionic embraces and developers will love more and more. Or the Ionic Native and Ionic Storage packages, something that makes life a lot easier for developers.

We can expect more good upgrades like these, which makes developing Ionic apps more easy in the future for everyone.

Would I do it again?

As you know my background is in native iOS development, and I still like Swift as a language (cmon, I even worked with Objective-C!). But JavaSCript is becoming more and more the language for everyone. Hell you can even write servers with JavaScript today.

Though, at the moment Ionic is the wiser decision for me now. The potential to build for the web, major mobile platforms and even for desktop using Electron is something nothing can beat.

Also, you can’t deny the job opportunities for all Angular developers (which you are more or less with Ionic) that are currently coming up everywhere. Being skilled with JavaScript is a skill people will look for over the next years for sure.

And as native and mobile emerge more and more, being able to develop for all platforms makes you very attractive to all employers that are using a modern technology stack.

Finally, keep in mind: This framework is still young compared to stuff like Java!

Ok it’s a framework vs. a language, but I think you get the point.

I have never regret my decision to stick to Ionic, and I’ll continue to work with it and wait for the next innovations the team brings out.

If you want to learn Ionic and make your own hands-on experience, the Ionic Academy is a perfect place to take your first steps together.

Happy Coding,
Simon

The post Why I Switched to Ionic (And Never Regret My Decision) appeared first on Devdactic.

Building Your Own Ionic WordPress Client with WP-API

$
0
0

If you are familiar with WordPress you know that since a few versions ago all instances have a public REST API. Of course I had to jump in when I saw a new WordPress API wrapper library for Angular 2+, created by the awesome Julien Renaux.

Although you could use the WordPress REST API without any additional library directly from your Ionic app, we will still make use of Juliens package because we don’t have to use the URLs for the routes but just the functions of the library.

In this tutorial we will start by integrating the library into a new Ionic project. We will then write our own WordPress Provider to separate the calls from our code view even more.

Finally, we will create a list of latest WordPress posts fetched from the API and a single view to show each article in full length.

ionic-wp-api-anim

If you want to get the full app ready to start simply insert your email below!

Prerequisite

Before going through this tutorial you should be familiar with Angular 2+ and Observables. You also need to have the latest version of Ionic set up on your machine.

If you want to learn Ionic with step-by-step video courses, hands-on training projects and a helpful community who has your back, then take a look at the Ionic Academy.

Checkout the Ionic Academy

Setting up our Ionic app

We start as always with a blank new Ionic app. By now we can skip the “–v2” flag because our app will be automatically started with that version since a recent update, so Ionic 3+ is now the standard for your new apps.

Additional we install the wp-api-angular which is the wrapper for our WordPress instance. If you haven’t installed typings yet, you might also want to do that now.

Finally, generate a provider for our logic and a page for a single post item. Go ahead and run:

ionic start devdacticWordpress blank
cd devdacticWordpress
npm install -g typings
npm install wp-api-angular --save
ionic g provider wpProvider
ionic g page PostPage

To make use of the Wp-api-angular package we need to configure it so it can play nicely with our Ionic app. Therefore, we have to export a function with the URL to our own WordPress page. We also need to load a few more dependencies (and our own created provider WpProvider) and use our special WpApiLoaderFactory for the WpApiModule.

Now go to your src/app.module.ts and insert:

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

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { HttpModule } from '@angular/http';

import { Http } from '@angular/http';
import { WpProvider } from '../providers/wp-provider';
import { 
  WpApiModule,
  WpApiLoader,
  WpApiStaticLoader
} from 'wp-api-angular'

export function WpApiLoaderFactory(http) {
  return new WpApiStaticLoader(http, 'https://devdactic.com//wp-json/');
}

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    HttpModule,
        WpApiModule.forRoot({
      provide: WpApiLoader,
      useFactory: (WpApiLoaderFactory),
      deps: [Http]
    }),
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    WpProvider
  ]
})
export class AppModule {}

Of course this currently uses the Devdactic URL, so make sure to change that URL to your own. If you can serve the app now without any problems everything is configured fine and we can continue with actually using the library.

Creating a WordPress Provider

We could use the library directly for our calls, but I still prefer to put the logic into an additional provider. Therefore, we wrap our calls to WordPress using the wp-api library into our created provider.

Also, we create 2 classes Post and User and map our REST call results into more friendly objects.

Inside the constructor of our provider we also grab the list of users from WordPress so we can easily show an avatar for each user at the post list later. Otherwise, we would have to make the call to retrieve user information over and over, so this saves us some http calls.

To get a list of posts we use the getList function which will return as an array of objects. For each of those objects we create a new Post object, and to get the image of each post we get a bit freaky: We assign an Observable to the media_url property which will also use the wp-api and load the link to the image.

This helps to easily create the view later, as we can just use the property with the aync pipe and our image will be displayed, no further crazy loading of stuff there!

Now open your src/providers/wp-provider.ts and insert:

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
import { WpApiPosts, WpApiMedia, WpApiUsers } from 'wp-api-angular';

export class Post {
  public media_url: Observable<string>;
  constructor(public authorId: number, public id: number, public title: string, public content: string, public excerpt: string, public date: string, public mediaId?: number) { }
}

export class User {
  constructor(public id: number, public name: string, public userImageUrl: string) { }
}

@Injectable()
export class WpProvider {
  users: User[];

  constructor(public wpApiPosts: WpApiPosts, public wpApiMedia: WpApiMedia, public wpApiUsers: WpApiUsers) {
    this.wpApiUsers.getList()
      .map(res => res.json())
      .subscribe(data => {
        this.users = [];
        for (let user of data) {
          let oneUser = new User(user[ 'id' ], user[ 'name' ], user[ 'avatar_urls' ][ '96' ]);
          this.users.push(oneUser);
        }
      })
  }

  getPosts(): Observable<Post[]> {
    return this.wpApiPosts.getList()
      .map(res => res.json())
      .map(data => {
        var posts = [];
        for (let post of data) {
          let onePost = new Post(post[ 'author' ], post[ 'id' ], post[ 'title' ][ 'rendered' ], post[ 'content' ][ 'rendered' ], post[ 'excerpt' ][ 'rendered' ], post[ 'date' ], post[ 'featured_media' ]);
          onePost.media_url = this.getMedia(onePost.mediaId);
          posts.push(onePost);
        }
        return posts;
      });
  }

  getMedia(id: number): Observable<string> {
    return this.wpApiMedia.get(id)
      .map(res => res.json())
      .map(data => {
        return data[ 'source_url' ];
      });
  }

  getUserImage(userId: number) {
    for (let usr of this.users) {
      if (usr.id === userId) {
        return usr.userImageUrl;
      }
    }
  }

  getUserName(userId: number) {
    for (let usr of this.users) {
      if (usr.id === userId) {
        return usr.name;
      }
    }
  }
}

As we load and fill the array of users inside the constructor, we can create 2 plain functions to search for the right user by id inside this array to get the user image and user name.

If you want to load more attributes of a post, just inspect the result of getList() and add those to the Post class. For example you could grab Tags or categories as well, but for new we keep it simple and move on!

Loading our WordPress data

We haven’t seen much of our code in action by now, so we now implement the view and class to load and display our list of WordPress posts.

As our provider still returns an Observable, our array of posts here is of the type Observable which can be handled easily inside our view later.

I also added a loading controller to indicate that we are loading stuff at the start of the app, and we dismiss this loading after we got data from our provider using .do().

To get the name and image of a user, we can easily rely on our provider and those calls are not asynchronous as we have preloaded the users and information before!

If we want to open a single post, we push a new page on our navigation stack and pass the post object through the navParams to our next page. We are only using the name ‘PostPage’ as we make use of lazy loading, which was introduced with Ionic 3!

If you want more information on lazy loading and upgrading to Ionic 3, check out this quick win.

Otherwise, continue and open your src/pages/home/home.ts and insert:

import { Component } from '@angular/core';
import { NavController, LoadingController, Loading } from 'ionic-angular';
import { WpProvider, Post } from '../../providers/wp-provider';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  loader: Loading;
  posts: Observable<Post[]>;

  constructor(public navCtrl: NavController, public wpProvider: WpProvider, public loadingCtrl: LoadingController) {
    this.presentLoading();
    this.posts = this.wpProvider.getPosts();
    this.posts.subscribe(data => 
        this.loader.dismiss();
    });
  }

  getUserImage(id: number) {
    return this.wpProvider.getUserImage(id);
  }

  getUserName(id: number) {
    return this.wpProvider.getUserName(id);
  }

  openPost(post: Post) {
    this.navCtrl.push('PostPage', {post: post});
  }

  presentLoading() {
    this.loader = this.loadingCtrl.create({
      content: "Loading..."
    });
    this.loader.present();
  }
}

The last step to show something in our app is to hook up the according view.

As we have prepared all of our data and types in a good way, we can now iterate over our array of posts using the async pipe. Each Ionic card will be tappable and calls our function to open the next page.

Inside the card the image of the featured image of the post is displayed (remember, we assigned an Observable to that property!) and below the image we display the information about the author.

Inside the content of the card we now have the title and the excerpt, which we assign to the innerHTML property as this has some HTML tags inside most of the time and by doing this we trust the HTML (potential harmful!) and see the formatted HTML code like a end user inside the card. Otherwise you would see all the tags printed out, which is of course not a good idea.

Prepare your view inside src/pages/home/home.html and insert:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      Ionic + Wordpress
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-card *ngFor="let post of posts | async" (click)="openPost(post)" tappable>
    <img [src]="post.media_url | async">
    <ion-item>
      <ion-avatar item-left>
        <img [src]="getUserImage(post.authorId)">
      </ion-avatar>
      <h2>{{ getUserName(post.authorId) }}</h2>
    </ion-item>
    <ion-card-content>
      <ion-card-title>
        {{ post.title }}
      </ion-card-title>
      <div [innerHTML]="post.excerpt"></div>
    </ion-card-content>
  </ion-card>
</ion-content>

Our app is now ready to run, so if you start it up you should see a list of post elements displayed nicely like in the image below!
ionic-wordpress-list

Showing a Single WordPress Post

The last missing piece is to display a full post, but we have already prepared everything for this as well. If we click a card, the next page will be pushed along with the post object.

Note: If might be the case that the CLI is generating your page and module file in a strange way, therefore make sure you import the IonicPageModule inside your module file at src/pages/post-page/post-page.module.ts, like below:

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { PostPage } from './post-page';

@NgModule({
  declarations: [
    PostPage,
  ],
  imports: [
    IonicPageModule.forChild(PostPage),
  ],
  exports: [
    PostPage
  ]
})
export class PostPageModule {}

If all of that is correct, we just have to assign the navParams value to a post object inside the src/pages/post-page/post-page.ts like this:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Post } from '../../providers/wp-provider';

@IonicPage()
@Component({
  selector: 'page-post-page',
  templateUrl: 'post-page.html',
})
export class PostPage {
  post: Post;

  constructor(public navCtrl: NavController, public navParams: NavParams) {
    this.post = navParams.get('post');
  }
}

Finally, to display the elements of the post we use again the innerHTML syntax but this time the content of our post object. Go ahead and finish the view inside src/pages/post-page/post-page.html:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>{{ post.title }}</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <img [src]="post.media_url | async">
  <div [innerHTML]="post.content" padding></div>
</ion-content>

Now your own little Ionic WordPress client is ready and can be extended with all kinds of features you like!

Conclusion

The wp-api-angular package makes it really easy to connect your Ionic app to a WordPress page. You can easily craft a app for you or your customers around their WordPress page by following this approach.

There is a lot more you can do with the wrapper, we have only touched a few functions by now so go ahead and inspect what else is possible.

Kudos again to Julien for developing this awesome helper!

You can find a video version of this article below!

Happy Coding,
Simon

The post Building Your Own Ionic WordPress Client with WP-API appeared first on Devdactic.

How to Add Animations To Your Ionic App (2 Different Ways!)

$
0
0

One of the most viewed articles on Devdactic is about Animations for Ionic Apps. Today we will take look at 2 different but both great ways to easily Animate our Ionic 2+ app!

In this post we will take a look at how to integrate the Angular way of doing animations by using the Web Animations API. You can find more about Web Animations API in this great post.

Besides that we will also add an external packages for animation to our app as an alternative for people who are not so fancy about the first way. So it’s something in here for everyone!

Prerequisite

Before going through this tutorial you should be familiar with Angular 2+ and the general Ionic concepts. You also need to have the latest version of Ionic set up on your machine.

If you want to learn Ionic with step-by-step video courses, hands-on training projects and a helpful community who has your back, then take a look at the Ionic Academy.

Checkout the Ionic Academy

Using Web Animations

angularanimations
With the Web Animations API we will build an effect like in the image above. Of course not super fancy, but this post is more about getting animations for your Ionic app up and running, not who can build the most freaky key frames animation.

To use web animations we need to install the Angular animations package and also the web animations polyfill so our animations will work in every browser. If you don’t install it, your animations might work on your local machine but perhaps not on the devices later.

You can also create a blank new project for this app, then you can install the dependencies like this:

npm install web-animations-js @angular/animations@4.0.0 --save

To make use of the polyfill we need to add something to our src/app/main.ts anywhere:

import 'web-animations-js/web-animations.min';

Ok we got the dependencies and polyfill, finally we need to add everything we need to our module. Especially this means we need the BrowserAnimationsModule, so go ahead and import it in your src/app/app.module.ts

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
...
...
imports: [
    BrowserModule,
    BrowserAnimationsModule,
    IonicModule.forRoot(MyApp)
  ],

As you have already seen, the goal is to simply animate a text block to appear and disappear, but in a very gentle way. If we simply toggle the alpha value, the element would plop and there would be now animation flow, therefore we create an animations block inside our @Component decorator which is the Angular way of adding animations

Inside this block you can define all kind of flows, in our case our element will have 2 different states: visible and invisible.

These 2 states are inside what is called a trigger. This is more or less they keyword we will also use later on inside the HTML to connect the animation to elements.

Now, both of our states got a very simple styling, either opacity 0 or 1. We could now already switch between states, but we want it to be animated.

Therefore we define the transition and use the wildcard pattern ‘* => *‘ which means whenever the state changes to another state, do this. And in this case, we want it to be animated for .5s which is half a second.

Now open your src/pages/home/home.ts and insert:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { trigger, state, style, transition, animate } from '@angular/animations'

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  animations: [
    trigger('myvisibility', [
      state('visible', style({
        opacity: 1
      })),
      state('invisible', style({
        opacity: 0
      })),
      transition('* => *', animate('.5s'))
    ])
  ]
})
export class HomePage {
  visibleState = 'visible';

  constructor(public navCtrl: NavController) { }

  toggleVisible() {
    this.visibleState = (this.visibleState == 'visible') ? 'invisible' : 'visible';
  }
}

The toggleVisible function helps to change the state of our variable, which will be connected with our trigger in the next step.

If you have any questions so far, just leave a comment below!

Otherwise, we continue with the actual view. There is not really much we need to do besides adding a button to call our toggle function, and adding the actual element that will be animated.

To do so, we simply apply the trigger with @ to the element, and we pass it the value of visibleState so the trigger will get noticed once that value changes.

Inside your src/home/home.html this would look like this:

<ion-content padding>

  <button ion-button (click)="toggleVisible()">Toggle it!</button>
  
  <p [@myvisibility]="visibleState">
    I am sometimes here and sometimes there.
  </p>

</ion-content>

Through the trigger myvisibility the element will get appeared if the state of the variable visibleState changes.

Pretty cool, huh?

Of course this was the most basic of all possible animations. But this way shows you the concept of Angular animations, which might be rather strange and new to some of you. But once you use it a few times, I’m sure you will feel quite comfortable writing your animations with Javascript.

If you want to get deeper into animations, the Ionic Academy also offers a course on animations!

Using External Packages

The previous way is the general, basic way of adding all kinds of animation to your Ionic app. This way is a bit more for the lazy ones or those that are simply not really skilled with CSS animations or keyframes. I count myself to that group as well from time to time, just because it’s so easy to use code that already does exactly what you need.

We will animate a button very easily, which will in the end look like the animation below. Remember, doing this with the previous way would involve some solide tinkering about which part of the animation has which length, how much to expand and so on.
animatecss

We will use a library called css-animator which helps us to use something like animate.css with Angular 2+.

First of all install the package inside your app running:

npm install --save css-animator

Now we also need to load animate.css, which is possible in 2 ways.For the simplicity of this article we will simply import a link to the hosted file inside our src/index.html somewhere inside the head area:

<head>
<!-- other stuff... -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">

You could also add the package with NPM as well and add a special copy config to automatically copy the file to your build folder. For a production app, I would recommend this and you can find more about including CSS or JS files from NPM packages here.

Now back to our business.

Like before we also need to import some stuff, so open your src/app/app.module.ts and load the AnimationService and AnimatesDirective:

import { AnimationService, AnimatesDirective } from 'css-animator';
...
...
 declarations: [
    ...
    AnimatesDirective
 ]
 providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    AnimationService
  ]

The directive will now help us to already use animations without anything else.

Simply go to your src/pages/home/home.ts and insert this button which is inside a div block that has our animations directive:

<ion-content padding>
  <div animates #animation="animates" text-center>
    <button ion-button (click)="animation.start({type: 'rubberBand', duration: '1000'})">Click me!</button>
  </div>
</ion-content>

If you run this code, you should see our button animation called rubberBand.

This is perhaps the most easiest way to add the predefined animations which you can check out here.

The package also allows us to create animations using an AnimationBuilder, so let’s take a final look at how to use them on a different way.

Now we need to grab a reference to our DOM element by using @ViewChild and the name of the element. Inside a function we can now directly animate the nativeElement of our child with an animation using the AnimationBuilder.

Add this code to your src/pages/home/home.ts:

import { Component, ViewChild } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AnimationService, AnimationBuilder } from 'css-animator';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild('myElement') myElem;
  private animator: AnimationBuilder;

  constructor(public navCtrl: NavController, animationService: AnimationService) {
    this.animator = animationService.builder();
  }

  animateElem() {
    this.animator.setType('flipInX').show(this.myElem.nativeElement);
  }
}

As you can see we need to import both AnimationBuilder and AnimationService, and the second is also inject inside the constructor to initialise our builder.

Now we still need to change our view so that we actually have a viewChild like the one we are looking for.

Therefore, change your src/pages/home/home.html to this:

<button ion-button (click)="animateElem()">Animate it!</button>
<ion-card #myElement>
  <ion-card-header>My Animation Card</ion-card-header>
  <ion-card-content>So much awesome content and animations. AMAZING!</ion-card-content>
</ion-card>

Now we got a basic Ionic card we can animate!

Hit the button and the card should do the flipInX animation like in the animation below!

animatecssservice

Conclusion

You have learned 2 ways to animate your Ionic app: The standard Angular way and using external packages.

Actually I think both have their pros and cons, so building all animations by hand can be quite painful especially if you are not really a designer or have no experience with CSS animations (or no interest in them). An external package however makes you dependent on other peoples code, so perhaps the package won’t work with Ionic 5+ and you are stuck in older version for that reason.

If you just want to have a few animations so your app looks more charming, try out the package.

If you are serious about your app and rely on all animations because your app would suck otherwise, perhaps build them with the Web animations API!

You can find a video version of this article below!

Happy Coding,
Simon

The post How to Add Animations To Your Ionic App (2 Different Ways!) appeared first on Devdactic.

How to Build An Ionic App with Firebase and AngularFire 4

$
0
0

When it comes to building an Ionic app with a solid backend, the current choice for many people is Firebase. And for reasons.

The process of connecting an Angular app to Firebase is fairly easy in combination with the great AngularFire package, which is currently at the state of a release candidate for a new version 4. We will be using that version to build a simple cloud based shopping app with Ionic and Firebase!

Once we are done with the app our result inside the app and Firebase database might look like in the image below.
firebase-shopping-list

Setup the App

We start y creating a blank new Ionic app. With the new Ionic CLI 3 there are now changes for these commands so you should be fine to run:

ionic start devdacticShopping blank
cd devdacticShopping
npm install angularfire2@4.0.0-rc0 firebase --save
ionic g provider firebase

We only need the AngularFire package at the currently latest version and the official Firebase package. Besides the packages we generate a FirebaseProvider which will be our connection to Firebase within the app.

Now we also need to create our app inside Firebase, so go ahead and sign in or connect your Google account if you haven’t done already. Inside your Firebase console you have the option to create a new app, so do it now and select a region where you think your users will most likely live.

firebase-create-project

When you now go into your app you will see a view with 3 circles allowing you to add Firebase to your app. You can already copy most of the code from the “Add Firebase to your web app” overlay because we need it in the next step!

Configure our Firebase Connection

Now that we got the config for the connection we can jump right into our Ionic app and configure AngularFire. We use the copied config and paste it above our module insie src/app/app.module.ts.

We also import our new provider, and finally the different packages of AngularFire as those are now separate and not all in one!

Finally we call initializeApp() with the config for our app to easily establish the connection to Firebase.

Go ahead and change your module file to:

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

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

import { HttpModule } from '@angular/http';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AngularFireModule } from 'angularfire2';
import { FirebaseProvider } from './../providers/firebase';

const firebaseConfig = {
    apiKey: "YOURKEY",
    authDomain: "domain.firebaseapp.com",
    databaseURL: "https://domain.firebaseio.com",
    projectId: "yourvalues",
    storageBucket: "dmaoin.appspot.com",
    messagingSenderId: "yourvalues"
  };

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

Before we dive into the rest of the code we need to change the Firebase security rules (for now). If you havenÄ’t heard of them, you can specify some JSON rules for your data nodes to prevent read or write access to different parts of your database.

In our case we are not using authentication here so we can disabled the rules. Navigate inside Firebase to Database -> Rules and change your rules to these dumb rules:

{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

Now everyone can read and write the data, but for now that’s fine.

Create our Firebase Provider

Our Firebase Provider will handle all the exchange of data between our app and Firebase, or between our App and AngularFire in this case.

We need to import the database module from AngularFire and create 3 functions to either get a list of items, add an item or remove an item of our shopping list.

All of these operations can be easily performed by calling list() with the name of our node (we just say it will be “shoppingItems”) on our AngularFire database.

If we add push() a new node will be inserted with an automatically created id, and if we call remove() we can remove a node again by its id!

Now go ahead and change your src/providers/firebase/firebase.ts to:

import { Injectable } from '@angular/core';
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';

@Injectable()
export class FirebaseProvider {

  constructor(public afd: AngularFireDatabase) { }

  getShoppingItems() {
    return this.afd.list('/shoppingItems/');
  }

  addItem(name) {
    this.afd.list('/shoppingItems/').push(name);
  }

  removeItem(id) {
    this.afd.list('/shoppingItems/').remove(id);
  }
}

Nothing really fancy, but this will help us in the next step inside our view.

I know many people would use AngularFire directly from the view, but I still like to keep these things separate from our actual class that controls the view. Let me know your opinion on this if you think different!

Loading & Displaying Data from Firebase

We can already load the data, but we can’t show it. So let’s change that!

Inside our HomePage we will assign the list of items to our array which has the type FirebaseListObservable, so we will always see any updates on this object if we use it correct.

Inside the view we will have a simple input field, so whenever addItem() is called we add the current value of our input to our shopping list bucket through our provider.

For remove we will pass the id of the object from our view to the function here and then delete it. Really, no magic in this class so open the src/pages/home/home.ts and insert:

import { FirebaseService } from './../../providers/firebase-service';
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { FirebaseListObservable } from 'angularfire2/database';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  shoppingItems: FirebaseListObservable<any[]>;
  newItem = '';

  constructor(public navCtrl: NavController, public firebaseProvider: FirebaseProvider) {
    this.shoppingItems = this.firebaseProvider.getShoppingItems();
  }

  addItem() {
    this.firebaseProvider.addItem(this.newItem);
  }

  removeItem(id) {
    this.firebaseProvider.removeItem(id);
  }
}

To wrap everything up it would be good to see our result on the screen.. Therefore we build a list of items, and each of these items can be slide to the side to reveal the remove button.

Above the list we add our very simple input field so we can also capture and add new shopping items.

Add this to your src/pages/home/home.html:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      Shopping List
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-row>
    <ion-col col-9>
      <ion-item>
        <ion-input type="text" [(ngModel)]="newItem" placeholder="New Shopping item"></ion-input>
      </ion-item>
    </ion-col>
    <ion-col>
      <button ion-button (click)="addItem()">Add!</button>
    </ion-col>
  </ion-row>

  <ion-list>
    <ion-item-sliding *ngFor="let item of shoppingItems | async">
      <ion-item>
        {{ item.$value }}
      </ion-item>
      <ion-item-options side="right">
        <button ion-button color="danger" icon-only (click)="removeItem(item.$key)"><ion-icon name="trash"></ion-icon></button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>
</ion-content>

If you run your app now, you should be able to add, remove and most important see all updates inside the app and our Firebase database, just like in the image below!

firebase-shopping-list

Conclusion

Adding Firebase to your Ionic project is a matter of minutes, and establishing the connection through AngularFire is as easy as always with the latest update.

If you also want to use authentication, you also need to import another module from AngularFire but the use is as easy as the database!

You can find a video version of this article below, there we still use the old Ionic CLI but that only changes a few names.

Happy Coding,
Simon

The post How to Build An Ionic App with Firebase and AngularFire 4 appeared first on Devdactic.


How to Build Ionic Twitter Integration with Timeline and Compose

$
0
0

Integrating Twitter in your Ionic app is something really interesting, and from the number of responses and the times how often I’ve written a Twitter post I’m pretty sure this updated one for Ionic 3+ is really needed.

Inside this tutorial we will build an Ionic app with Twitter login, and after login we use our OAuth kes to make signed requests to the Twitter REST API through a nice NPM package called ng2-twitter.

For this tutorial you need a Twitter App and also Fabric account, but both is free to create and only takes minutes!

Once we are done you will be able to login, show a users timeline and also send out tweets.
twitter-compose

Prerequisite

We’ll need some API keys for Twitter and and additional service, so let’s create them now.

First, you need a Twitter App because otherwise you won’t get any token and won’t be alowed to make specific calls like we want to. Go ahead and create an app; there’s nothing special you have to insert into those fields.

Make sure to have your Access Level set to at least Read and Write, but if you also add the permission for “direct messages” you’ll get the most power through the API later.

The next step is to get a key from Fabric. As the Twitter connect plugin states, there are 3 steps:

  1. Login to your Fabric account (or create one, if you don’t have one) and go to the Twitter install guide.
  2. Find the AndroidManifest.xml code block on that page.
  3. Find the API Key inside that code block.

The block should look like this:

// AndroidManifest.xml
<meta-data
    android:name="io.fabric.ApiKey"
    android:value="FABRIC_KEY"
/>

It’s not very hard to find these keys, so now you should have both your Twitter App keys and Fabric keys ready and at hand. You are ready to add the Twitter connect plugin to your app!

Setting up our Ionic Twitter App

We create a blank new Ionic app like always. To make use of Twitter login we install the according Twitter Connect plugin from Ionic Native as well as the in app browser to open tweet URLs later and of course we install ng2-twitter for our requests later.

When adding the Cordova plugins, we need to pass the Fabric API key from the first step of our tutorial to the plugin, so make sure you add the right key!

Finally we also create new pages and a provider for our app, so go ahead now and run:

ionic start devdacticTwitter blank
cd devdacticTwitter

npm install --save @ionic-native/in-app-browser
npm install --save @ionic-native/twitter-connect
npm install --save ng2-twitter

ionic cordova plugin add twitter-connect-plugin --variable FABRIC_KEY=fabric_API_key
ionic cordova plugin add cordova-plugin-inappbrowser

ionic g page login
ionic g page timeline
ionic g provider twitter

To hook up everything correctly we need to import the new stuff into our src/app/app.module.ts and add it to the array of providers like this:

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

import { MyApp } from './app.component';
import { HttpModule } from '@angular/http';

import { InAppBrowser } from '@ionic-native/in-app-browser';
import { TwitterConnect } from '@ionic-native/twitter-connect';
import { TwitterService } from 'ng2-twitter';
import { TwitterProvider } from '../providers/twitter/twitter';

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

For the last step you need the consumer key and secret key from your Twitter app, because they need to be added to your config.xml. You can find the values inside your Twitter app inside Keys and Access Tokens -> Application Settings. Go ahead and add these two entries inside the config.xml inside the widget block:

<widget>
  // ....
  <preference name="TwitterConsumerKey" value="<Twitter Consumer Key>" />
  <preference name="TwitterConsumerSecret" value="<Twitter Consumer Secret>" />
</widget>

Take a deep breath for one last step.. It’s just a tiny one.

We need to change the entry point of our app to our new LoginPage, therefore go to your src/app/app.component.ts and change it to:

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

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage:any = 'LoginPage';

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

I think we are finally ready to see some code, right?

give-code-soon

Making HTTP calls to Twitter REST

When we login through Twitter Connect we will receive a token and tokenSecret back after a successful login. These tokesn are needed to make authorized REST calls later through our provider which we will implement next.

The provider needs these tokens, so we allow to set them from outside (what we will use after user login) and we also need again our consumer Key and scret of our Twitter app. Of course here in the code is not the best place, I’m still wondering where it would be the safest to have these keys..

If you have an idea where it’s most safe to keep them please post below the article!

For now we go ahead and add 2 functions which are postTweet() to simply submit a tweet (yes, this is possible with the right access!) and also getHomeTimeline() to load the timeline of the current user.

These functions make use of our ng2-twitter, because otherwise we would need a lot of work here with different keys and signing objects like in my previous post on the Ionic Blog.

But now things work a bit smoother and we can pass in the needed variables to the calls of the Twitter REST API like the status text or the tweet count.

Go ahead and implement the src/providers/twitter/twitter.ts like this:

import { TwitterService } from 'ng2-twitter';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class TwitterProvider {
  token = null;
  tokenSecret = null;
  consumerKey = 'YOURCONSUMERKEY';
  consumerSecret = 'YOURCONSUMERSECRET';

  constructor(private twitter: TwitterService) { }

  setTokens(token, tokenSecret) {
    this.token = token;
    this.tokenSecret = tokenSecret;
  }

  postTweet(text) {
    return this.twitter.post(
      'https://api.twitter.com/1.1/statuses/update.json',
      {
        status: text
      },
      {
        consumerKey: this.consumerKey,
        consumerSecret: this.consumerSecret
      },
      {
        token: this.token,
        tokenSecret: this.tokenSecret
      }
    )
      .map(res => res.json());
  }

  getHomeTimeline() {
    return this.twitter.get(
      'https://api.twitter.com/1.1/statuses/home_timeline.json',
      {
        count: 10
      },
      {
        consumerKey: this.consumerKey,
        consumerSecret: this.consumerSecret
      },
      {
        token: this.token,
        tokenSecret: this.tokenSecret
      }
    )
      .map(res => res.json());
  };

}

Here would also be the place to add your own functions and more calls to Twitter, there is of course a lot more you can do besides receiving some tweets and posting stuff!

Building Twitter Login

We now get to an even more interesting part…the login!

The view will only consist of a button, to make this more beautiful is left as an exercise for the reader. Go ahead and change your src/app/pages/login/login.html to:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      Devdactic + Twitter
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <button ion-button full (click)="loginWithTwitter()">Login with Twitter</button>
</ion-content>

The next step is the actual login process. After having setup all these keys everywhere there’s not really much we have to do here. We also add a few loading and alert notifications just to make the process more smooth.

Once we got a successful result we setup our own provider with the right tokens and continue to the TimelinePage of our app.

You can change your src/app/pages/login/login.ts to:

import { TwitterProvider } from './../../providers/twitter/twitter';
import { TwitterConnect } from '@ionic-native/twitter-connect';
import { Component } from '@angular/core';
import { IonicPage, NavController, AlertController, LoadingController, Loading } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
  loading: Loading;

  constructor(public navCtrl: NavController, private twitter: TwitterConnect, private twitterProvider: TwitterProvider, private alertCtrl: AlertController, private loadingCtrl: LoadingController) { }

  public loginWithTwitter() {
    this.showLoading();
    this.twitter.login().then((data) => {
      this.twitterProvider.setTokens(data.token, data.secret);
      this.loading.dismiss().then(() => {
        this.navCtrl.setRoot('TimelinePage');
      });
    }, error => {
      this.showError(error);
    });
  }

  private showLoading() {
    this.loading = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    this.loading.present();
  }

  private showError(text) {
    this.loading.dismiss().then(() => {
      let alert = this.alertCtrl.create({
        title: 'Fail',
        message: text + '\nMake sure to setup Twitter account on your device.',
        buttons: ['OK']
      });
      alert.present(prompt);
    });
  }

}

As you can see, it’s really not that much in that controller, which is a good sign. Next stop: Timeline!

Showing Timeline and sending Tweets

I guess this part is what you waited for all the time, right?

As we have put most of the complex stuff into our provider we can now simply reap the fruits of our hard work. Our array of tweets is an Observable which will be filled from our provider after the page is loaded.

We can also trigger this loadTimeline() from a pull to refresh which we will add to our HTML in the next step. And that’s actually already everything here we need to receive the current timeline!

When we want to create a new tweet we show a simple alert view with an input for the message. Once the user sends this message we again make use of our TwitterProvider and use the send function.

Additional we have 2 helper functions to show the correct date of a tweet and also to open an URL of a Tweet.

Go ahead and add all of this now to your src/pages/timeline/timeline.ts:

import { TwitterProvider } from './../../providers/twitter/twitter';
import { Component } from '@angular/core';
import { IonicPage, NavController, Loading, LoadingController, AlertController, ToastController } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { InAppBrowser } from '@ionic-native/in-app-browser';

@IonicPage()
@Component({
  selector: 'page-timeline',
  templateUrl: 'timeline.html',
})
export class TimelinePage {
  tweets: Observable<any[]>;
  loading: Loading;

  constructor(public navCtrl: NavController, private twitterProvider: TwitterProvider, private alertCtrl: AlertController, private loadingCtrl: LoadingController, private toastCtrl: ToastController, private iab: InAppBrowser) {
  }

  ionViewWillEnter() {
    this.loadTimeline();
  }

  public loadTimeline(refresher?) {
    this.showLoading();
    this.tweets = this.twitterProvider.getHomeTimeline();
    this.tweets.subscribe(data => {
      this.loading.dismiss();
      refresher.complete();
    }, err => {
      refresher.complete();
      this.showError(err);
    });
  }
  public composeTweet() {
    let prompt = this.alertCtrl.create({
      title: 'New Tweet',
      message: "Write your Tweet message below",
      inputs: [
        {
          name: 'text'
        },
      ],
      buttons: [
        {
          text: 'Cancel'
        },
        {
          text: 'Tweet',
          handler: data => {
            this.postTweet(data.text);
          }
        }
      ]
    });
    prompt.present();
  }
  public dateForTweet(dateString) {
    let d = new Date(Date.parse(dateString));

    // http://stackoverflow.com/questions/3552461/how-to-format-a-javascript-date
    var datestring = ("0" + d.getDate()).slice(-2) + "-" + ("0" + (d.getMonth() + 1)).slice(-2) + "-" +
      d.getFullYear() + " " + ("0" + d.getHours()).slice(-2) + ":" + ("0" + d.getMinutes()).slice(-2);

    return datestring;
  }

  public openLinkUrl(url) {
    let browser = this.iab.create(url, 'blank');
  }

  public postTweet(text) {
    this.showLoading();
    this.twitterProvider.postTweet(text).subscribe(res => {
      this.loading.dismiss();
      let toast = this.toastCtrl.create({
        message: 'Tweet posted!',
        duration: 3000
      });
      toast.present();
    }, err => {
      this.showError(err);
    });
  }
  private showLoading() {
    this.loading = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    this.loading.present();
  }

  private showError(text) {
    this.loading.dismiss();
    let alert = this.alertCtrl.create({
      title: 'Error',
      message: text,
      buttons: ['OK']
    });
    alert.present(prompt);
  }

}

If you have any questions to the code above simply let me know. It’s a big block of code but I think after doing all the stuff before everything should be more or less clear. If not, you know what to do.

We come to the end and have to compose the UI for our timeline by pulling out different properties of a tweet object.

It’s best when you log out the object and take a look at it yourself to see what everything you got there.

In our example we build some nice cards with the user image, name, tweet, possible tweet image and also link to a URL which will be opened with the in app browser.

Go ahead and finish this tutorial by replacing everything inside src/pages/timeline/timeline.html with this:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      My Feed
    </ion-title>
    <ion-buttons end>
      <button ion-button icon-only (click)="composeTweet()">
        <ion-icon name="create"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-refresher (ionRefresh)="loadTimeline($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>

  <ion-card *ngFor="let tweet of tweets | async">

    <ion-item>
      <ion-avatar item-left>
        <img src="{{tweet.user.profile_image_url}}">
      </ion-avatar>
      <h2>{{tweet.user.name}}</h2>
      <p>{{dateForTweet(tweet.created_at)}}</p>
    </ion-item>

    <img src="{{tweet.extended_entities.media[0].media_url}}" *ngIf="tweet.extended_entities">

    <ion-card-content>
      <p>{{tweet.text}}</p>
    </ion-card-content>

    <ion-row>
      <ion-col *ngIf="tweet.entities.urls.length > 0">
        <button ion-button clear small (click)="openLinkUrl(tweet.entities.urls[0].url)">
          <ion-icon name="open"></ion-icon>
          <div>Open Link</div>
        </button>
      </ion-col>
    </ion-row>

  </ion-card>

</ion-content>

Now everything is done and you can use your own little Twitter client, just like in the image at the start of this article (but of course with different tweets).

Recap

The beginning and configuration phase was a bit tough and dry, but once you got that right there’s nothing that can stop you from using the Twitter REST API!

Being able to pull the data from twitter on your own is somehow a cool feeling, perhaps you are already working on an app with Twitter integration?

Let us know below and leave a comment if you’ve read until here!

Happy Coding,
Simon

The post How to Build Ionic Twitter Integration with Timeline and Compose appeared first on Devdactic.

15 Reasons Why You Should Develop Ionic Apps

$
0
0

If you plan to develop your next app and are undecided whether you go for native or a cross-platform framework, this guide will give you 15 rock solid reasons you should think of Ionic as your framework of choice.

1. One Code To Rule Them All

Ionic is a framework to develop cross-platform apps for iOS, Android and Windows. As such, one of the most obvious reasons is that you only need to learn one real programming language, which is JavaScript to develop for 2 or 3 different platforms. This is of course a major advantage compared to native app development, where you have one very specialised project for each platform!

Inside your project you will also have HTML and CSS, but those don’t really count anyway and I guess all developers have used these 2 friends at some point of his/her career.

If you have a project with only one language, of course more of your developers can understand it and work on it. You don’t have to train new developers with other languages

And compared to Java or Swift, JavaScript is actually a language that most developer already know or have used, and it’s super beginner friendly. Which brings us to the next point.

2. Low Entrance Barrier

If you have ever developed with JavaScript, you know that you will see results pretty fast. And although Ionic uses the Framework Angular which you need in all projects, getting started with Ionic takes you a few minutes maximum the first time.

Unlike Swift or Java we don’t have a special interface builder inside our IDE, but taking the first steps and creating our first elements, views and native elements is easily done even for beginners through HTML.

After you install Ionic, you start a new project based on one of the Ionic starter templates and you can directly preview your “app” inside your browser. The whole process might take you less than 5 minutes! Downloading the Android SDK or Xcode might alone already take an hour..

Ionic comes with a solid getting started guide, and in places like the Ionic Academy people can keep learning new stuff every day.

So once you start your app you will notice…

3. Beautiful User Interface Components

Yes, the UI of Ionic apps looks great out of the box – something they are very proud of. Ionic comes with predefined styling for different components, so all the elements you can use will look and feel like native elements.

This means, they will look even native across different platforms, so on Android our items will get the Material Design touch and on iOS the current iOS look! All of this comes automatically, right out of the box.

Whenever you use a component of Ionic, you will immediately notice that they already look quite nice how they come. This really helps to develop a good-looking prototype a lot faster, as you can simply rely on their styling and don’t have to put your own touches on each element!

4. Native Plugins

If you are new to cross-platform development, of course you might ask yourself: How do I get access to the device features with JavaScript?

Indeed a good question, which is solved by Cordova. Cordova is built right into Ionic and packages our app into a webview and builds a native project once we start a certain command. And through a Cordova bridge we can also use native device features like camera, email client and almost everything you can imagine.

Ionic puts another layer of simplicity on top of this by offering a package called Ionic Native. This package wraps Cordova Plugins into a more friendly Angular way so we can use them more easy and natural inside our app!

If you fear you can’t access something, just search for “Cordova plugin xyz” and I bet there is already a wrapper for what you need. And if really can’t find something, you can still develop your own Cordova plugins (but then you need native knowledge).

5. Powerful yet Simple CLI

Ionic comes with a very handy command line interface. Whenever you need to create a new project, compile your project to native projects or do anything else inside your project, their CLI will support you a lot.

Need to create new files & folders? Let the CLI handle that part so you automatically follow the right architecture!

Want to preview your app? Start a live reload server with preview, showing you even the styling for different platforms right inside your browser!

The CLI is your tool belt for Ionic and comes with great tools to make your life easier!

6. You Have to Learn Angular

Doesn’t sound like a benefit or argument for Ionic at first, right?

But I think it really is. It’s not like you are only learning Ionic, a mystical framework from which none of the knowledge you can ever reuse.

No, you are learning Angular 80% of your time! And Angular is one of the best frameworks for modern web development out there, perhaps even the best (I’m not a big fan of who is the best, so others can decide this if they want).

If your developers learn Ionic, they will also be able to work with pure Angular projects after your mobile project.

And if you are a developer yourself, you get the benefit of learning one mighty framework which allows you to build stuff for the web and mobile in the end! Isn’t that awesome?

So in my eyes it’s a big plus for your that you are forced to learn a (new) framework with Angular, which you might be scared of first but the benefits for you can’t be denied.

7. Latest Web Technologies

We already talked about Angular, which is always at the top of the game, but we are also making use of things like TypeScript which allows us to use the most modern JavaScript features of ES6 and even types.

Many people I have talked to as a consultant couldn’t believe how modern JavaScript with TypeScript looks like, if you come from an object oriented language you will feel almost at home!

Ionic is always on the edge of new development, so they also have support for PWA directly baked into Ionic!

8. Development & Testing Speed

If you have ever developed native applications you know that it can take a lot of time to develop and debug when you always have to re deploy your app to a simulator or a device. This process is so much faster with Ionic!

As already mentioned before, Ionic has a feature called “ionic lab” which will bring up your browser and show you how your app will look on the different platforms, even side by side. Plus, whenever you make changes to the code the live reload is triggered and everything is automatically updated.

Coming myself from iOS development, this feature feels so damn good and helps all developers to make progress faster on their apps.

9. Enterprise Companies Go For Ionic & Support it

It’s not like only nerdy developers and small businesses give Ionic a try. Enterprise companies and brands already feel the pressure to change their mobile landscape, and they turn towards Ionic as one of the best cross-platform frameworks.

Even Apple featured an App developed with Ionic on the Appstore!

Ionic is not a company which will be broke next week. They go some serious investors and are not running out of money, also they generate income through their Ionic Cloud services or products like the Ionic Creator.

10. Outstanding Support & Community

You measure how good a framework is by how active the community is. And the Ionic community is awesome helpful!

People like Josh Morony or Jorge Vergara pump out new Ionic tutorials almost every week, and there is also an Ionic Slack channel.

There are countless books or places like the Ionic Academy which offer special support tailored to your needs, so you will never be alone when learning and developing with Ionic!

11. The Ecosystem

From some of the links you might have already noticed that there is more to Ionic than just the framework itself.

Ionic is constantly trying to make your developer life easier by offering new features, packages or even full services which help you to implement stuff like push notifications, analytics or user authentication.

Further packages like a set of icons called Ionicons which come bundled with your app or the already mentioned CLI complete your package and offer you everything you need to immediately develop awesome apps.

12. Decreased App Project Costs

This is the classic argument for the higher management level.

Compared to developing 2 separate apps for iOS and Android, maintaining and bugfixing in 2 repos you can save a lot of time and money with Ionic. All changes can be done in one place, the same code, same language, same developer!

The equation is not that it will only take you 50% of the time due to problems that can still arise from targeting different platforms, but something like 70-80% is realistic for a cross-platform project.

Also, the ongoing cost when you deliver new features and fix stuff is definitely reduced a lot, so savings when you develop your project cross-platform are guaranteed. If you also take into account that the developers can reuse Angular code for your web app or use the learned skills from this project for your next project, deciding on Ionic is an absolute no brainer.

13. It’s Open Source

Haven’t mentioned this one before, right? Yeah, it’s open source!

This means everything is free, you don’t have to pay for any licence to develop your enterprise apps (besides for the iOS and Android stores).

Additional you can always track what the Ionic team is working on, which bugs and issues are open and you could even start your own pull request to fix stuff on their Github repository.

14. The Good Old Performance Myth

Cross platform development or especially “hybrid apps” have a bad taste for some people, a major reason were the (really) shitty performance some years ago of these apps, but devices, the browsers and the frameworks have changed a lot. And another major reason was that Facebook called betting on HTML5 over native was the biggest mistake they did.

Really, this is your counter argument?

A while ago I published another article on the topic of hybrid myths, feel free to check it out.

Baseline: If you are not as big as Facebook (and I bet you are not) this is no argument for you. The performance of Ionic apps is to most parts equal to “standard” native apps and users won’t see or feel any difference. It’s a different story when we talk about mobile games, but for 90% of the apps Ionic could deliver the same performance like other apps.

15. It’s FUN

We have seen 14 more or less technical reasons why you should develop Ionic apps, but I saved this final one as it really means a lot to me:

Developing Ionic apps is fun!

I’ve developed countless tutorials, courses and projects, and still every time I start a new project I’m fired up and love how easily and fast you can actually develop something. Once I built a tiny game in only one evening.

As a developer, we often have to do something, but working with Ionic feels most of the time like a pleasure, and this reason shouldn’t be ignored. Developer happy = faster development!

Conclusion

Do you have still open questions in your mind? Feel free to ask anything below!

Hopefully these reasons helped you to decide whether Ionic is good for you or not. And the best idea is now to just give it a try to see if I lied on those points or if you can agree with them.

You can also get a 7 day Ionic Crash Course where we take the first steps together, simply scroll a bit down and insert your email to get started!

Happy Coding,
Simon

The post 15 Reasons Why You Should Develop Ionic Apps appeared first on Devdactic.

Dynamic Theming Your Ionic App

$
0
0

Theming your Ionic app is an awesome way to quickly change the styling for all parts of your app. But what happens if you want to change your styling while running, like toggling a day or night mode?

We can’t change the selected theme of our Ionic app at runtime, so we need to become a bit more creative. In this tutorial we will see how to quickly change the styling of our app just like in the image below!

ionic-dynamic-style-toggle

Preparing our App

We start as always with blank Ionic app and generate a provider which will be used later to tell us which theme is currently used. Go ahead and run:

ionic start devdacticDynamicStyle blank
cd devdacticDynamicStyle
ionic g provider settings

Now inside our app we need to create 2 files inside the src/theme folder, as these will reflect how our different themes will look like. Call the first file theme.light.scss and insert:

.light-theme {
  ion-content {
    background-color: #fff;
  }

  .toolbar-background {
    background-color: #fff;
  }
}

The second one is called theme.dark.scss and you can insert this:

.dark-theme {
  ion-content {
    background-color: #090f2f;
    color: #fff;
  }

  .toolbar-title {
    color: #fff;
  }

  .header .toolbar-background {
    border-color: #ff0fff;
    background-color: #090f2f;
  }
}

Now we got 2 styling files which define some CSS classes for either a light or a dark theme. We also need to make them available, so put these import statements somewhere in your src/theme/variables.scss:

@import "theme.light";
@import "theme.dark";

We have now created and imported our themes, but as the class is never added those stylings will never be applied. So that’s where our route is taking us soon.

Creating the Settings provider

But before we get there we need to implement our helper provider. The provider holds the current selected theme, we can change the theme and we can grab the theme.

In general nothing special, but we want to make sure that our app always get’s the latest selected theme, and therefore we use a type called BehaviourSubject which inherits from Subject and then from Observable, so it’s more or less a special type of Observable.

Using this type has 2 benefits for our app:

  • We can set a start value which will be emitted to all subscribers at first subscription
  • We can call next() and all subscribers will immediately get the new value

So inside our Constructor we set the initial value, when we want to set it to a new value we call the next() method and finally we return it to our views as an Observable because there we don’t need any more specials and can simply use it like a standard Observable.

open your src/providers/settings/settings.ts and insert:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/Rx';

@Injectable()
export class SettingsProvider {

    private theme: BehaviorSubject<String>;

    constructor() {
        this.theme = new BehaviorSubject('dark-theme');
    }

    setActiveTheme(val) {
        this.theme.next(val);
    }

    getActiveTheme() {
        return this.theme.asObservable();
    }
}

Now we can change the theme from everywhere inside our app and the subscribers will be notified about the new value so we can change it accordingly.

Toggling our App Theme

To toggle our app theme, we add a simple button and toggle function to our page. We also subscribe to the current value and always update our variable inside the class once a new value comes to us in the subscribe() block.

Open your src/pages/home/home.ts and insert:

import { SettingsProvider } from './../../providers/settings/settings';
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  selectedTheme: String;

  constructor(public navCtrl: NavController, private settings: SettingsProvider) {
    this.settings.getActiveTheme().subscribe(val => this.selectedTheme = val);
  }

    toggleAppTheme() {
    if (this.selectedTheme === 'dark-theme') {
      this.settings.setActiveTheme('light-theme');
    } else {
      this.settings.setActiveTheme('dark-theme');
    }
  }

}

Now we need to craft a little view around this and add the button to toggle our styling. Nothing really fancy here, so open your src/pages/home/home.html and change it to:

<ion-header>
  <ion-navbar>
    <ion-title>
      Night & Day
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <p text-center>I shine at night and glow at day.</p>
  <button ion-button full icon-left (click)="toggleAppTheme()">
    <ion-icon  name="bulb"></ion-icon>Toggle Theme
  </button>
</ion-content>

We are now able to toggle our style, but nothing happens!

Did you think it would work now
?

Well the most important part is still missing, because we are currently just updating a random variable of a provider but never really use it.

Adding the final Piece of Magic

This brings us to the last missing piece of our dynamic theming. The trick we use is to apply the selected theme as a class to the root component of our app!

Therefore, we need to also subscribe to the value like we did before inside our src/app/app.component.ts like this:

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

import { HomePage } from '../pages/home/home';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage:any = HomePage;
  selectedTheme: String;
  
  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, private settings: SettingsProvider) {
    this.settings.getActiveTheme().subscribe(val => this.selectedTheme = val);

    platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

There is always a HTML file connected to this root component, and this is the place where we add the class using the Angular way of dynamically adding a class.

Open your src/app/app.html and add it like this:

<ion-nav [root]="rootPage" [class]="selectedTheme"></ion-nav>

Now whenever we change our variable inside the provider (through our toggle) the new theme will be set as a Conclusion

We could now add even more themes and toggle them dynamically to change the UI of our Ionic app at runtime. Of course you need to be aware what CSS you define at the root level because it will be applied to all pages, so try to be specific with your CSS selectors there to only target what you really want to change.

You can find a video version of this article below.

Happy Coding,
Simon

The post Dynamic Theming Your Ionic App appeared first on Devdactic.

How to build an Ionic Calendar App

$
0
0

Out of the box there is no Ionic component to display a calendar inside your app, but what if you want to give people the chance to add events and display everything inside a good-looking view?

Like always we can rely on a helpful third-party package called Ionic calendar. In this tutorial we will build our own Ionic calendar app to add events into an almost Apple like looking calendar view! Of course we could also access the device calendar to add events, but that’s not helping us regarding showing some sort of table to the user.

Once done our app will look like in the image below, where we can insert new events into our own custom calendar view.

ionic-date-app

Setting up the Calendar App

As always we start with a blank new Ionic app. We create another page where we will add details for a new event, and we install the ionic-calendar package plus 2 more packages. The first is needed as a dependency of the calendar, the second is Moment.js which helps us to transform some of our dates more easily than we could do with pure Javascript.

Go ahead now and start your app like this:

ionic start devdacticCalendar blank
cd devdacticCalendar
ionic g page eventModal
npm install ionic2-calendar --save
npm install moment --save
npm install intl@1.2.5 --save

To make use of the calendar we also need to import it, so open your src/app/app.module.ts and insert:

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

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

import { NgCalendarModule  } from 'ionic2-calendar';

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

Building the Calendar View

The view of our main calendar is actually super easily, because all the heavy work is done by our package. Inside the nav bar we add a button to call our addEvent() function, and inside the content we only add the calendar.

We take a look at all the options in a second, for now simply add this to your src/pages/home/home.html:

<ion-header>
  <ion-navbar color="primary">
    <ion-title>
      {{ viewTitle }}
    </ion-title>
    <ion-buttons end>
      <button ion-button icon-only (click)="addEvent()">
        <ion-icon name="add"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content>
<calendar [eventSource]="eventSource"
        [calendarMode]="calendar.mode"
        [currentDate]="calendar.currentDate"
        (onEventSelected)="onEventSelected($event)"
        (onTitleChanged)="onViewTitleChanged($event)"
        (onTimeSelected)="onTimeSelected($event)"
        step="30"
        class="calendar">
      </calendar>
</ion-content>

We haven’t actually used everything of that plugin, but what we used so far is:

  • eventSource: The data we feed to the calendar view
  • currentDate: Needed to mark “today”
  • onEventSelected: Handle a tap on a single event
  • onTitleChanged: Happens when we swipe to a new month
  • onTimeSelected: Happens when we select a day or time
  • step: Used for accuracy of a day or week view

You can check out all options here again.

Now that we got the view let’s connect it with our controller. As we see we need to create some functions, and most of them are pretty basic.

When we want to add an event, we will show a new page to set up the information. Once the modal view is dismissed we create the event and push it to our eventSource. To update the information inside the view we also need to use setTimeout so the data will be reloaded inside the view.

If we click on a single event we will simply alert out some information. This is a point where you could also drill deeper into a day view or show more information for a single event.

Make sure your controller contains all the needed information and functions for the calendar, so go ahead and change your src/pages/home/home.ts to:

import { Component } from '@angular/core';
import { NavController, ModalController, AlertController } from 'ionic-angular';
import * as moment from 'moment';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  eventSource = [];
  viewTitle: string;
  selectedDay = new Date();

  calendar = {
    mode: 'month',
    currentDate: new Date()
  };
  
  constructor(public navCtrl: NavController, private modalCtrl: ModalController, private alertCtrl: AlertController) { }

  addEvent() {
    let modal = this.modalCtrl.create('EventModalPage', {selectedDay: this.selectedDay});
    modal.present();
    modal.onDidDismiss(data => {
      if (data) {
        let eventData = data;

        eventData.startTime = new Date(data.startTime);
        eventData.endTime = new Date(data.endTime);

        let events = this.eventSource;
        events.push(eventData);
        this.eventSource = [];
        setTimeout(() => {
          this.eventSource = events;
        });
      }
    });
  }

  onViewTitleChanged(title) {
    this.viewTitle = title;
  }

  onEventSelected(event) {
    let start = moment(event.startTime).format('LLLL');
    let end = moment(event.endTime).format('LLLL');
    
    let alert = this.alertCtrl.create({
      title: '' + event.title,
      subTitle: 'From: ' + start + '<br>To: ' + end,
      buttons: ['OK']
    })
    alert.present();
  }

  onTimeSelected(ev) {
    this.selectedDay = ev.selectedTime;
  }
}

We are now ready to run our Ionic Calendar app, but we can’t add any events so let’s wrap this up with the last missing piece.

Adding User Events

We already implemented the function to display our second view, so this view will allow the user to insert some details for a new event. Of course we could also store some own information here and improve the date display, but for now this is enough.

Open your src/pages/event-modal/event-modal.html and change it to:

<ion-header>
  <ion-navbar color="primary">
    <ion-buttons start>
      <button ion-button icon-only (click)="cancel()">
        <ion-icon name="close"></ion-icon>
      </button>
    </ion-buttons>
    <ion-title>Event Details</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item>
      <ion-input type="text" placeholder="Title" [(ngModel)]="event.title"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label>Start</ion-label>
      <ion-datetime displayFormat="MM/DD/YYYY HH:mm" pickerFormat="MMM D:HH:mm" [(ngModel)]="event.startTime" [min]="minDate"></ion-datetime>
    </ion-item>

    <ion-item>
      <ion-label>End</ion-label>
      <ion-datetime displayFormat="MM/DD/YYYY HH:mm" pickerFormat="MMM D:HH:mm" [(ngModel)]="event.endTime" [min]="minDate"></ion-datetime>
    </ion-item>

    <ion-item>
      <ion-label>All Day?</ion-label>
      <ion-checkbox [(ngModel)]="event.allDay"></ion-checkbox>
    </ion-item>
  </ion-list>

  <button ion-button full icon-left (click)="save()">
    <ion-icon name="checkmark"></ion-icon> Add Event
  </button>
</ion-content>

We just add a bunch of standard Ionic inputs and controls to build out the event object of that class.

Speaking of the class, here we only have a few interesting points. For one, we pass in the currently selected date from our calendar view. By doing this we can automatically set the start date to that previously selected date like any good calendar!

When we want to save or add the event, we will simply dismiss the page and pass the current event as an object. We already added the logic to catch this data and create a new event from it, so now we only have to add this to our src/pages/event-modal/event-modal.ts:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ViewController } from 'ionic-angular';
import * as moment from 'moment';

@IonicPage()
@Component({
  selector: 'page-event-modal',
  templateUrl: 'event-modal.html',
})
export class EventModalPage {

  event = { startTime: new Date().toISOString(), endTime: new Date().toISOString(), allDay: false };
  minDate = new Date().toISOString();

  constructor(public navCtrl: NavController, private navParams: NavParams, public viewCtrl: ViewController) {
    let preselectedDate = moment(this.navParams.get('selectedDay')).format();
    this.event.startTime = preselectedDate;
    this.event.endTime = preselectedDate;
  }

  cancel() {
    this.viewCtrl.dismiss();
  }

  save() {
    this.viewCtrl.dismiss(this.event);
  }

}

We are done and you should be able to see your calendar and add your own events now!

Conclusion

With the help of this plugin it’s actually not really hard to implement a calendar with Ionic. You can of course change the CSS so it fit’s your app, and you could add more logic to store and retrieve events from your own backend.

This tutorial should give you a good starting point if you want to implement your own calendar!

You can find a video version of this article below.

Happy Coding,
Simon

The post How to build an Ionic Calendar App appeared first on Devdactic.

How to Use Ionic SQLite Queries & Pre-Populated Database

$
0
0

Although the Ionic Storage package is great to store almost any kind of data, many of the readers wrote they are using MySQL on the backend side and need some more equivalent storage inside their Ionic app.

In this post we will see how to easily import SQL data into our Ionic app, and how to work with queries to retrieve or modify our stored data!

Note: If you have some sort of MySQL database you should still work on a REST API to deliver the data and don’t work directly on the database.

Setting up our App

We start with a blank Ionic app and install the Cordova SQLite plugin to access the database. Additional we add the SQLite Porter plugin as well as the according Ionic Native NPM packages so we can populated our SQL database from e.g. a given SQL dump. Go ahead and run:

ionic start devdacticSql blank
cd devdacticSql
ionic g provider database
ionic cordova plugin add uk.co.workingedge.cordova.plugin.sqliteporter
ionic cordova plugin add cordova-sqlite-storage
npm install --save @ionic-native/sqlite-porter @ionic-native/sqlite

We also create a provider for all of our database interaction right here.

As said before we want to fill our database with some initial values. You can do this of course with the standard SQLite wrapper but you would either have to prepare each statement accordingly or split up your SQL dump into the right format, which is sometimes not a good idea.

The SQLite Porter plugin would also allow to import JSON data, but here we stick to SQL.

In our case it’s enough to have a SQL dump like the one below, so for testing create a file at src/assets/dummyDump.sql and insert:

CREATE TABLE IF NOT EXISTS developer(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,skill TEXT,yearsOfExperience INTEGER);
INSERT INTO developer(name, skill, yearsOfExperience) VALUES ('Simon', 'Ionic', '4');
INSERT INTO developer(name, skill, yearsOfExperience) VALUES ('Jorge', 'Firebase', '2');
INSERT INTO developer(name, skill, yearsOfExperience) VALUES ('Max', 'Startup', '5');

We just create one new table and insert some data sets.

Next we need to add everything we installed to our module and load the plugins and stuff, so change your src/app/app.module.ts to:

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

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

import { IonicStorageModule } from '@ionic/storage';
import { HttpModule } from '@angular/http';

import { DatabaseProvider } from '../providers/database/database';

import { SQLitePorter } from '@ionic-native/sqlite-porter';
import { SQLite } from '@ionic-native/sqlite';

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

Now we are all set up to use our database!

Writing the SQL Database Provider

The provider will act as some middle layer for all interactions to the database, just like in other examples where we perform REST calls or have any kind of specific business logic.

Once our platform is ready we create or open a new SQLite database on our device, and once we are ready we can fill the database with our SQL dump. But we only do this on initial startup, because otherwise we would insert the initial data over and over again.

You might also notice the BehaviourSubject we are using, perhaps this is new to you. Basically it’s kind of an Observable and we can emit new values to the subscribers by calling next() on it. We use this mechanism to let our class later know that the database is ready for interaction so we can prevent race conditions between platform load, open database and so on.

To fill our database we use the previously added SQLitePorter where we pass in the database and also the content of our SQL dump which we need to load before.

Before we go through the last functions, open your src/providers/database/database.ts and insert:

import { Injectable } from '@angular/core';
import { Platform } from 'ionic-angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
import { SQLitePorter } from '@ionic-native/sqlite-porter';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/Rx';
import { Storage } from '@ionic/storage';

@Injectable()
export class DatabaseProvider {
  database: SQLiteObject;
  private databaseReady: BehaviorSubject<boolean>;

  constructor(public sqlitePorter: SQLitePorter, private storage: Storage, private sqlite: SQLite, private platform: Platform, private http: Http) {
    this.databaseReady = new BehaviorSubject(false);
    this.platform.ready().then(() => {
      this.sqlite.create({
        name: 'developers.db',
        location: 'default'
      })
        .then((db: SQLiteObject) => {
          this.database = db;
          this.storage.get('database_filled').then(val => {
            if (val) {
              this.databaseReady.next(true);
            } else {
              this.fillDatabase();
            }
          });
        });
    });
  }

  fillDatabase() {
    this.http.get('assets/dummyDump.sql')
      .map(res => res.text())
      .subscribe(sql => {
        this.sqlitePorter.importSqlToDb(this.database, sql)
          .then(data => {
            this.databaseReady.next(true);
            this.storage.set('database_filled', true);
          })
          .catch(e => console.error(e));
      });
  }

  addDeveloper(name, skill, years) {
    let data = [name, skill, years]
    return this.database.executeSql("INSERT INTO developer (name, skill, yearsOfExperience) VALUES (?, ?, ?)", data).then(data => {
      return data;
    }, err => {
      console.log('Error: ', err);
      return err;
    });
  }

  getAllDevelopers() {
    return this.database.executeSql("SELECT * FROM developer", []).then((data) => {
      let developers = [];
      if (data.rows.length > 0) {
        for (var i = 0; i < data.rows.length; i++) {
          developers.push({ name: data.rows.item(i).name, skill: data.rows.item(i).skill, yearsOfExperience: data.rows.item(i).yearsOfExperience });
        }
      }
      return developers;
    }, err => {
      console.log('Error: ', err);
      return [];
    });
  }

  getDatabaseState() {
    return this.databaseReady.asObservable();
  }

}

To subscribe to the Database ready state we use our own Behaviour subject and return it as an Observable to whoever wants to subscribe.

To get all stored developers in our database we perform a simple SELECT statement against our table and transform the result from the SQL statement to a useful array which we can return to our calling class!

If we now want to add a developer, we can again perform a SQL query to insert the new data into our database.

Basically, you can now write any SQL query you can come up with to search data or perform whatever action you need to do!

Loading and Shwoing SQL Data

It’s time to actually use our new provider, so first of all we craft small view with a few input fields to capture new data for the database.

Below the inputs we show a list of all developers, which will be gathered from our database (hopefully). Go ahead and change your src/pages/home/home.html to:

<ion-header>
  <ion-navbar>
    <ion-title>
      Developer Data
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-item>
    <ion-label stacked>What's your name?</ion-label>
    <ion-input [(ngModel)]="developer.name" placeholder="Developer Name"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label stacked>What's your special skill?</ion-label>
    <ion-input [(ngModel)]="developer.skill" placeholder="Special Skill"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label stacked>How long have you been working?</ion-label>
    <ion-input [(ngModel)]="developer.yearsOfExperience" placeholder="Years of experience"></ion-input>
  </ion-item>
  <button ion-button full (click)="addDeveloper()">Add Developer Info</button>

  <ion-list>
    <ion-item *ngFor="let dev of developers">
      <h2>{{ dev.name }}</h2>
      <p>{{ dev.yearsOfExperience }} years of {{ dev.skill }} Experience!</p>
    </ion-item>
  </ion-list>
</ion-content>

Nothing really special here. Now we only need to connect the according functions and everything should work.

As we have most of the logic inside our provider, the class of our view is quite small.

Remember the BehaviourSubject?

Inside our constructor we subscribe to the database state, and once the value changes to true we try to load our initial developer data. By doing this we prevent that the constructor calls the load before the database is actually ready, which would result in an error and no data inside our view.

When we add a developer we expect the database to be ready already, we just call the according function addDeveloper() of our provider to insert a new row into our SQLite database.

Open your src/pages/home/home.ts and change it to:

import { DatabaseProvider } from './../../providers/database/database';
import { Component } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  developer = {};
  developers = [];

  constructor(public navCtrl: NavController, private databaseprovider: DatabaseProvider, private platform: Platform) {
    this.databaseprovider.getDatabaseState().subscribe(rdy => {
      if (rdy) {
        this.loadDeveloperData();
      }
    })
  }

  loadDeveloperData() {
    this.databaseprovider.getAllDevelopers().then(data => {
      this.developers = data;
    })
  }

  addDeveloper() {
    this.databaseprovider.addDeveloper(this.developer['name'], this.developer['skill'], parseInt(this.developer['yearsOfExperience']))
    .then(data => {
      this.loadDeveloperData();
    });
    this.developer = {};
  }

}

That’s all, now you only need to make sure you run this app on a device/simulator as we make use of the underlying SQLite database which is not available inside your browser if you use the preview or lab function!

Conclusion

With the right plugins we are able to import SQL data (or even JSON structure) into the SQLite database of a device with Ionic. The Ionic Storage plugin is a bit easier to use and also works inside our browser but has dropped support for the query() function, so if you really on this function you might need to access your database directly through these plugins.

You can also find a video version of this article below!

Happy Coding,
Simon

The post How to Use Ionic SQLite Queries & Pre-Populated Database appeared first on Devdactic.

Viewing all 183 articles
Browse latest View live