Building a Native App with Ionic, AngularJS, and Appery.io

For years, developers had to make a choice: build a single hybrid app with a so-so user experience, or build a native app for each platform with a great user experience. Developers don’t have to make this choice anymore. By integrating the Ionic SDK into Appery.io, developers can build enterprise HTML5/hybrid apps on a single code base that offer a native experience across all platforms. The Appery.io platform’s visual tooling lowers the skills barrier, empowering a broader base of developers and business analysts to create effective and intuitive mobile applications.

In this tutorial, you will use the Appery.io platform to build a mobile app. The tool set includes:

  • Ionic – native-like UI components
  • AngularJS – UI logic/binding
  • Appery.io App Builder – cloud-based drag and drop designer
  • Appery.io Backend Services – API backend for the app

What are you building?

You are going to build a todo app. The app will have two pages. On the first page, you will be able to see a list of all tasks and also mark a task complete (delete it). On the second page, you will be able to create a new task. You can see how the app looks below. The first page lists all the tasks. You can also mark a task completed (delete it). On the second page you can add a new task.

Before you start

Starting is very simple. There is nothing to download or install (cool, right?). You only need an Appery.io account. If you don’t already have an account, sign up for the Starter plan (free).

Let’s get started!

The first step is to create a brand new Ionic app.

Creating a new app

Creating a new app is easy and simple, since there is nothing to download, configure or setup.

  1. From the Apps page, click the Create new app button
  2. For app name, enter TodoApp
  3. Select Ionic AngularJS App and click the Create button

In a few seconds, a new app will be created and you should see the following:

Ionic_createapp_startpage

New Ionic app

Now that you have created a new app, next you are going to design the first page.

Designing the index page

Expand the Pages folder and click on the index page. The visual designer will load the page:

Ionic_designindex_open

Visual designer

An Ionic/AngularJS app comes with an index page. This is the main template page that defines header and footer elements (can also define a side menu component).

This is a visual designer, so most of the app UI will be built using drag and drop.  Let’s work on the header.

  1. Click the Header component, then in Properties view set the Color property to assertive.
  2. Select the Button component and drag and drop into the left-hand box in the header. It should look like this:

    Ionic_designindex_tasksbutton

    index page

  3. With the button selected, go to Properties and change the button Text to Tasks.
  4. Expand the Icon property, click the No icon button and set an icon for the button. Select the ion-navicon-icon that looks like this:
    Ionic_designindex_icon
  5. Now you need to add one more button. Drag and drop another Button component and place it on the right-hand side in the header.
  6. Set the button Text to New and set the Icon to ion-plus-circled that looks like this:
    Ionic_desingindex_iconplus

This is how your page should look:

Ionic_designidex_header

index page header

 

There’s just one more thing to do with the header. You want the header title to change based on the page currently loaded (the app has two pages: “tasks” and “create new task”). In order to change the title when the app is running, you need to bind the header to an AngularJS expression. When the app is running, the correct page title will be read from AngularJS scope and set in the page.

  1. Select the header and in Properties view, set the Text property to {{header.title}}. This is an AngularJS expression. This means that the object header and its property will be resolved when the app is running.
  2. Note the three tabs on the left side of the visual designer: Design, Scope, Binding. Open the Scope view. This view allows you to define AngularJS scope variables and functions. The init() function is already there. Click on Edit button to open the function for editing.
  3. Add these lines of code (in addition to the line already there):
    $scope.header = {};
    $scope.header.title = "Tasks";

    This code creates an object that will be present in AngularJS scope and hold the current page name. The expression that you set above will then display the correct page name.

We are done with the index page. That was pretty simple, right?

Next you are going to work on a page that displays all the tasks.

Designing the tasks page

Every new app comes with two pages. The index page that you already worked on and also Screen1 page. First, let’s rename the page.

  1. Hover the mouse over Screen1 file name until you see a blue icon on the right. Click the icon and select Rename
  2. Set the new name to tasks and click Rename

You are ready to design this page. This page will have a list that will display all the tasks. Inside the list there will be a button to mark a task completed (delete the task).

  1. Open the tasks page.
  2. Drag and drop the List component onto the page. The default list has three items.
  3. As you will be loading the tasks from a database, you just need one list item. Select the third (last) list item. Two icons will appear in the upper right corner. Click on the red icon to remove this item from the list:

    Ionic_designtasks_list

    Tasks page

  4. Repeat the same for the the other item (leave only one list item).

You should have a list with just one item.

  1. Click the item, you will see two icons in the upper right corner. Click the plus icon and a button will be inserted in the list item.
  2. In Properties, clear the button Text property. The expand Icon and set the icon to ion-trash-b icon.
  3. Select the list item again and in Properties expand Item Badge and set the Text to High.

Your page should look like this:

Ionic_designindex_listdone

Ionic list

 

Testing the app: browser and device

You can test your app in the browser (desktop or mobile) and you can also test the app on device as a hybrid app.

Testing in the browser

Testing your app during development in the browser is super easy. There is a Test button in the App Builder that will launch the real app in a new browser tab. Your app should look like this:

Ionic_testtasks

Testing in browser

Note that this is the real app running in the browser (this is not a simulator). If you would like, you can remove the frame by clicking Remove frame button.

Browser on mobile device

Go back to the App Builder and expand the Test button menu. You will see there is an option to make the app public. Once you make the app public, go back to the test page and click on View on phone link. You will see a QR code. Scan this QR code with your mobile device (you will need an QR scanner app) and it will launch the app in the browser on your device.

Testing on device (hybrid app)

It’s also very simple to test the hybrid app on the actual device. To simply test on the device, install the Appery.io Tester app (available for iOS and Android). Once the app is installed, sign in with your Appery.io user name and password. You will see the app you created. Tap the app, and the hybrid version of this app will be launched on the device.

Now that you know how to test your app, let’s work on the second page where you will be able to create a new task.

Designing the new task page

On this page you will be able to create a new task, set its priority and save it.

  1. Select Create new > Page. For page name enter newtask and click Create Page button
  2. Drag and drop the Input component
  3. In Properties, change the Placeholder value to New task
  4. Next drag and drop the Checkbox component. Set its Text value to High priority
  5. Now drag and drop the Button component.
    • Set the Text property to Save task
    • Set the Width property to Block
    • Set the Color property to calm

Your page should look like this:

Ionic_designnewtask_done

New task page

Now that you are done with the UI, next you are going to work on adding the app backend.

 Adding app backend – database

You need a place to store the tasks created. For that you are going to use a cloud database.

From the App Builder, click on Database link in the upper right corner to launch the database console.

  1. From the main Database page, click Create new database button. For database name enter taskDB and click Create.
  2. You just created a new database. Now you need to create a collection (table) to store the data. Click Create new collection. For collection name, enter task and click Add.  A new collection has been created.
  3. Now you need to add two columns to the collection.
    • Click +Col, for name enter name. Keep Type as String.
    • Click +Col, for name enter priority and set the Type to Boolean.

It’s very quick to enter sample collection data if you would like.  Click +Row and enter any task description and select true if you want it to be a high priority task. This is how your collection should look:

Ionic_db_task_sampledata

Database

Now that we’ve got an app backend, let’s work on integrating this backend with the app.

Generating APIs to connect to the backend

What’s nice is that the database you just created is already exposed via REST APIs, and as you may have guessed, it’s also very simple to get these APIs.

  1. In the App Builder, select Create new > Database Services. From the list of databases, select the database you just created.
  2. Expand the task collection. Here you can select which API services to import (generate). You need three services: CreateList and Delete.

    Ionic_db_importdbservices

    Generating API services

  3. Click Import selected services. If you open Services folder you will see the API services you just created.

Any service can be quickly tested. Open the taskDB_task_list_service service, then open the Test tab. Click the Test button. You should see the sample data you entered when you created the collection

Ionic_listservice_test

Testing REST API service

Before you use the services on the page, you also need to create the app model.

Creating an app model

An app model makes it easy to work with objects in the app that mimic the objects in the database.

  1. To create an app model open Project > Model.
  2. In the input field, enter Task and click Add.
  3. Now you are going to add three properties to the Task object. Click the Add button (on the right of Task) three times. Three properties will be added. Rename the properties to: _id, name, and priority. Only for priority, set the type to Boolean.
  4. You now need to create another object, a list that will hold a collection of tasks. In the top input field enter TaskList and click Add
    1. Change the Type to Array. A child element will be added.
    2. For the child element, change the Type to Task

Your model should look like this:

Ionic_model

App model

You have a Task object and a list of Tasks.

Now you are ready to use services on the page.

Setting up API services on tasks page

Setting up a service on a page usually involves the following steps:

  • Invoking the API from the page.
  • Saving data from service into AngularJS scope.
  • Using AngularJS expressions ({{..}}), binding the page to the scope to display data.

Getting all the tasks from the database

When a user opens the app, you want to load all tasks from the database.

  1. Open the tasks page.
  2. Open the Scope tab. The scope is where you will define scope variables and scope functions.
  3. First you need to define a scope variable. On the left side of the scope editor, enter tasks for the variable name. Set the Type to TaskList. It should look like this:

    Ionic_tasks_scope_variable

    Scope editor

  4. On the right side of the scope editor, enter loadTasks function name. Keep the type as Scope function and click Add.
  5. Click Edit for the function you just created.
  6. Place the mouse cursor inside the editor and click on Invoke service snippet button. Service invocation code snippet will be inserted.
  7. Next you need to set the service name to invoke. Delete the "service_name" (including quotes) and with the cursor between the brackets click ctrl-space to invoke code assist. Select taskDB_task_list_service from the popup. You can also always enter the name by hand. Your function should look like this:

    Ionic_tasks_scope_loadtasks1

    Scope editor – function

Next you are going to take the data returned from the service and map it to the scope.

You don’t need to create an AngularJS controller in Appery.io. A controller is automatically created for each page

You can quickly change how the Scope editor looks by selecting to show only Variables, Functions or both (Split). You can also position the view vertically or horizontally (default) by clicking the two buttons in the upper right corner.

Now it’s time to work on mapping.

  1. To save tasks into the scope, click the second Mapping button the function code. This mapping is done inside the success promise. A visual mapping editor will open. Using drag and drop create the following mapping:

    Ionic_tasks_mapping

    Mapping editor

  2. Click Save and return.

You will go back to the function and you will see the generated code from the mapping you just completed:

var tasks_scope = $scope["tasks"];
tasks_scope = success.data;
$scope["tasks"] = tasks_scope;

This is how the complete function looks:

Ionic_tasks_loadmapping_code

Scope function code

When you click on Mapping again, you won’t see the mapping connection that you created. In our next update, the mapping connection will stay there. If you need to make any changes to the mapping, you can delete the generated code and do the mapping again.

This is what happens:

  • The service is invoked
  • The data is copied to tasks scope variable.
  • Once the data is in the scope, it’s available to be displayed on a page
  • We don’t really handle a service (but you should in general)

Before you work on binding the UI to the scope, the init() function needs to be updated to invoke the function to load the tasks.

  1. Open init function for editing
  2. Add this line of code to invoke the function to load the tasks:
    $scope.loadTasks();

Let’s work next on displaying this data.

  1. Switch back to Design tab
  2. Select the list item and in Properties add a new attribute by starting to type ng-, you will see a list of all available AngularJS directives. You can type the full attribute name (ng-repeat) or select it from the list.
  3. For the attribute value, type task in and activate code assist by pressing ctrl-space and select tasks. The complete value should be: task in tasks.
  4. Now change the Text property of the list item to {{task.name}}.
  5. Expand the Item Badge property and set these values:
    • Set the Text property to {{task.priority?'High':'Normal'}}.
    • Set the Color property to {{task.priority?'assertive':'stable'}}.

You can go ahead and test the app again in the browser or on the device. When you entered sample data you set both task to a high priority. Enter another task and don’t mark it as high priority. When you run the app it should look like this:

Ionic_testtasks2

Testing tasks page in the browser

Now that the app displays all the tasks from the database, let’s work on marking a task complete – or delete it.

Marking a task completed (deleting)

When a user clicks on the icon with the trash can, the task should be deleted from the database. The first step is to create a function to delete the selected task.

  1. Open the Scope view.
  2. Create a new function called deleteTask with Scope function (default) type.
  3. To delete a task, you need to know which task to delete, thus you need to pass an id of the task to be deleted. Each function has an Arguments field. For the function just created enter id in that field.
  4. Click Edit to edit this function
  5. If you remember, you imported a delete service to delete a task. The code to invoke the service can be quickly imported by clicking Invoke service code snippet
  6. The service requires the id of the task to be deleted so you need to pass it to the service. You will use the requestData object already there. Add this as the second line of code:
    requestData = {"_id":id};
  7. Next you need to set the actual service name. Delete the "service_name" value. You can use code assist (ctrl-space) to help you find the service name or enter it manually. The service name is TaskDB_task_delete_service.

Your code should look like this:

var requestData = {};

requestData = {"_id": id};

Apperyio.get("TaskDB_task_delete_service")(requestData).then(
   function(success){
   },
   function(error){
   }
);

There are two more things to do before running the app. First, when a task is deleted, you need to update the list in the app. If the delete is successful, you want to refresh the list. Add loadTasks() function in the delete service success promise. This is how the final code looks:

var requestData = {};

requestData = {"_id": id};

Apperyio.get("TaskDB_task_delete_service")(requestData).then(
   function(success){
      $scope.loadTasks();
   },
   function(error){
   }
);

Second, you need to bind the delete button to this function.

  1. Switch to Design view.
  2. Select the delete button.
  3. In Properties, set the value of ng-click attribute to deleteTask(task._id). You can use code assist (ctrl-space) to help you with function selection.

Go ahead and test the app. Try deleting an item. You are going to work on the add task functionality next. For now, you can quickly add a new item by entering it directly in the database. For example, this is how the app looks after deleting two tasks:

Ionic_testtasks3

Testing in the browser

Now that you got the tasks page done, it’s time to wire everything for the new task page. But first navigation has to be added to the app.

Setting up navigation

There are two buttons in the header that you need to setup for navigation. Tasks button will navigate to the tasks page and New will take you to newtask page.

  1. To setup navigation or routing in AngularJS terms, open Project > Routing. You will see the default route there. It shows the page to load when the index page is loaded or when you launch the app.
  2. Instead of Screen1 default route name, change it to a more appropriate name: tasks.
  3. Enter new route name newtask.
  4. For page,  select the newtask page and click Add.

The final routing should look like this:

Ionic_routing

Routing editor

Now that you defined navigation, let’s wire the actual buttons. As the app uses the index template, it’s easy to define navigation in just one place.  Furthermore, to simply navigation, Appery.io makes a custom AngularJS directive to navigate from one page to another available called navigate-to. This directive is used like any other AngularJS directive such as ng-click or ng-repeat. You set it as an attribute.

  1. Open index page in Design view
  2. Select the Tasks button
  3. In Properties add navigate-to directive and set its value to tasks (that’s the route name). For directive name you can use code assist (ctrl-space) or just type the entire name.
  4. Repeat the same New button, setting the route name to newtaks.

You can test the app. When you click on New button you should see the newtask page:

Ionic_testrouting_newtask

Testing newtask page

You are almost done. Next you are going to work on saving a new task into a database.

Setting up API services on newtask page

Here you will get the data from the page, pass it to the service which in turn will save it into the database. Once the save is successful, you will navigate to the tasks page to see the newly added task.

  1. Open newtask page and switch to Scope view
  2. Create a scope variable to hold the input form the page. Name it task and set type to Task.

    Ionic_newtask_scope_variable

    Scope editor – variables

  3. Now it’s time to add a function. Add a function called addTask with default Scope function type
  4. Open the function for editing
  5. Insert Invoke service code snippet
  6. Change the service name to TaskDB_task_create_service

Now you need to map the data from scope and pass it to the service. As before, instead of writing code, you can use a visual mapping editor.

  1. Click on the first Mapping box inside the code editor. A visual mapping editor will open
  2. Using drag and drop, create the following mapping:

    Ionic_newtask_mapping

    Mapping editor

  3. Click Save and return to go back to Scope editor. The mapping code is automatically generated.
  4. You want to navigate to the tasks page once a new task has been successfully added. To do that, add
    Apperyio.navigateTo("tasks");

    in the services’ success callback.

Your final code will look like this:

var requestData = {};
requestData.data = Apperyio.EntityAPI('TaskDB_task_create_service.request.body', undefined, true);

var task_scope = $scope["task"];
requestData.data.name = task_scope.name;
requestData.data.priority = task_scope.priority;

Apperyio.get("TaskDB_task_create_service")(requestData).then(

   function(success){
      Apperyio.navigateTo("tasks"); // navigation 
   },
   function(error){}
);

Now you need to bind the page to the scope, as well as the button.

  1. Switch back to Design view.
  2. Select the input field and set its ng-model attribute to task.name. This will bind the input to the Task object in scope.
  3. Select the check box field and set its ng-model attribute to task.priority.
  4. Select the button and set its ng-click attribute to addTask().

Just one more thing left to do: when you navigate to newtask page, the header title says Tasks. It should say New task.

  1. Switch to Scope view and open the init function for editing.
  2. Add this line of code to change the header title:
    $scope.header.title = "New task";

Now you are done and ready to test the app.

Testing the app

You are done with the app and would like to run it. As we mentioned earlier in this tutorial, there are a number of ways to run this app.

Via the browser

You can quickly test in the browser by clicking the Test button.

To simplify launching the app on the device in the browser, you can scan a QR code (requires a barcode scanner app) and test the app on your device.

Ionic_test_qrcode

Launching the app via QR code

Don’t forget to make the app public inside the App Builder when testing on the device.

As hybrid app, on device

Ionic is the missing SDK for native apps and so you want to test the app on the device. That’s easy to do with the Appery.io Tester app. The app is free and available for iOS and Android. The tester app allows you to test the native apps and any native APIs without installing the app on the device. This is how the app looks when testing on Android:

Ionic_testerapp_android

Testing on device

Installing on the device

Another option is to install the app directly on the device. That’s also pretty simple to do, since Appery.io will create a binary file that’s ready to be installed on the device. To create the binary file, click Export in the App Builder:

Ionic_export

Export menu

The Appery.io cloud build service will quickly build a binary file that’s ready to be installed on a device or uploaded to the app store.

Every Appery.io apps bundles Apache Cordova. This means you can also use any Cordova APIs such as Camera, Contacts and others.

As you can see, building an app with natives APIs is also simple.

Getting app backup

We hope you will try this tutorial, but if you would like to try this app right away, you can download the app backup and create a new app from it (Create new app > From backup). Please complete the database setup as described in this tutorial. In the database console, go to Settings tab and copy the database API key. In the App Builder, open Services > TaskDB_settings and paste the API key for database_id.

Summary

This tutorial has showed you how to quickly build an app with a native user experience with Ionic, AngularJS, and Appery.io.