Build an app with Ionic Framework & Laravel5

In this tutorial we will be creating an app with ionic framework (a brilliant mobile app development framework by drifyco). We will be using the api that i have created in my previous blog post to get data from the server which is created in Laravel5. In this blog post i will be covering many topics like setting up ionic, setting up sass, auth, crud, ionic pull to refresh, ionic infinite scroll etc.

The API endpoints are as follows,

2015-12-12_18-06-50

So without further due, let’s get started.

Creating Ionic Project

For Creating Ionic Project, first make sure you have nodejs installed. If it is installed you are good to go. Now run the following command.

It will install both the cordova and ionic in your system globally due to -g  sign we added in the command, which means you can now use cordova and ionic commands from any directory in your system.

Now, ionic provides various templates to use as a starter projects. So we will use one of them. Switch to any directory where you want to create the ionic project and run the following command.

Where ionic_jokes is the name of your project and will be used as a directory name for your project.

CWindowssystem32cmd.exe_2015-12-09_11-41-14

Testing App

We have two options for testing the app, we can either use our browser (chrome, firefox) to test the app or we can use emulator/physical device. Unless you are not using any device specific feature, i would suggest you stick to browser for the testing purpose (easiest one).

Ionic Serve

Now switch to the just created project directory and run the follwing command.

What this command will do, it will start a live reload server and now you can see  your app running  in the browser. As you can see in the console, in my case it is running at http://localhost:8000

ionic_2015-12-09_11-42-04

The app in the browser will look similar to this. Now what this live reload server will do, it will see the files for changes if any change happens it will reload the browser page. So no need to refresh the page again.

2015-12-09_11-43-10

Ionic Run

Now the second option is to test the app in the emulator or actual device. For this first you need to install the development tools for the specific platform, like if you are developing for android then you need to download and install android sdk and android development tools. There are various tutorials that can help you with how to install and setup your system for android and ios development. So check them too.

Now i am assuming you have installed android sdk and android development tools on your machine (mine is windows machine, only because i can’t afford mac). Actually, windows is not that bad. So, the next step is to add the android platform to the ionic project. For this run the following command.

If everything went perfectly, you will see a screen similar to this.

CWindowssystem32cmd.exe_2015-12-09_11-41-29

Now after adding the platform you can connect your android device to your system. Make sure developer mode and usb debugging are on and the device specific drivers are installed on the system (windows). Now run the following command.

What this command will do is, it will build and run the app on your physical device. But if you don’t have physical device, then you can use android emulator, that you can create by going to AVD manager. After creating new virtual device. First you need to run the virtual device and then you can run the following command.

After running this command, you can see your app running in the emulator. But i would prefer browser or physical device. Emulator is very sluggish.

Setting Up Sass

Now we will setup Sass, if you don’t know about Sass, you should definitely check it out. It is a CSS preprocessor, whatever you write in Sass will be compiled to CSS in the end. But it gives extra advantage like we can use variables, functions etc. Ionic also encourages to use sass. So to setup Sass, run the following command.

Administrator_CWindowssystem32cmd.exe_2015-12-09_12-04-18

It is not mandatory to use sass with ionic. But it should be used.

Let’s see an example of how Sass can be beneficial. We will be using simple Sass variable to update the app top bar colors.

Open the ionic.app.scss  file and add the following variable.

You can now run ionic serve  and you can see your app will now look similar to this.

2015-12-12_17-35-11

Now wherever we have used that stable color in the app, it will be changed to new color. That is the simplest thing Sass can do.

Creating Routes

Throughout the app, the folder that you will be most interested in is www

Ionic uses ui-router by default so if you are not familiar with it. You need to have a look at it first. But it is very easy to learn if you are familiar with angular’s default router. We will create two new routes, one for auth and one for jokes. For this open the app.js  and add the following code snippet.

Now you need to create the login and jokes templates and AuthCtrl and JokesCtrl. For creating the templates go to www/templates folder and add login.html and jokes.html and add the following code.

Now the next step is to create the controllers AuthCtrl and JokesCtrl. Open the controllers.js file and add the following code.

Now run the ionic serve  and see the output.

The /jokes route will look like this

2015-12-12_17-58-51

and the /auth route will look like this.

2015-12-12_18-00-14

Now we will update the sidemenu, to update it open the menu.html  and update the ion-list  with this snippet.

Now the sidemenu will look similar to this.

2015-12-12_18-04-16

Ionic Auth (With Satellizer)

For authentication, we will use a token based authentication moude for angular called satellizer. The benefit of Satellizer is that when the user is logged in, a token is saved to the local storage. We know that to make request to our laravel api we need token every time, Satellizer makes sure to send the token with each request. So we don’t have to send the token manually.  let’s first start by including satellizer to our project by running,

Now, we need to include the satellizer script. Open index.html and add the script as follows:

Now we need to inject the satellizer as a dependency in app.js  as,

Now update the config function in app.js  as follows,

The $authProvider  is available via satellizer.

Now open the controllers.js and update the AuthCtrl as follows,

You can see we have used this code snippet in the AuthCtrl

What this snippet does is, when the user goes from one route to next, ionic by default adds back button, we don’t want back button to be added when we go from /auth to /jokes. Because we don’t want the user of the app to go back to auth again.

Now, run ionic serve  and go to /login route and try login with correct credentials, if everything worked perfectly, you can see the token in the browser local storage and you will be redirected to /jokes route

2015-11-13_22-39-14

CRUD Operations

I have explained crud operations in my previous angular post. So i am pasting the snippets here. The jokes controller and its template will look like this.

You can easily move most of the code to factory/service, if you like. For the sake of simplicity, i am placing everything in controller.

And the jokes.html  template will look like this.

Now you can run the server again and you can see the output will look similar to this.

2015-12-12_19-00-02

Now your app is fetching data from the actual server. We can view all the jokes, create new joke, edit the joke and delete the joke. For editing and deleting you need to swipe on any joke. 

For editing a joke, i am using ionic service called $ionicPoup  and the popup looks like this.

2015-12-12_19-04-03

Securing Routes

Now our app is working well, but there is one flaw. We are authenticating the user from the server and fetching and showing the jokes from the server. But we can see that, if the user is not authenticated, he/she can still go to /jokes route and if the user is authenticated, he/she can still go to the /auth route. We don’t want this to happen in our app. So we need to secure our routes.

For securing routes we will use a angular package called angular-permission, so let’s start by installing the package.

Now include the angular-permission script in the index.html

Now we need to add the permission module to the app.js dependencies array, now it is look like this.

Now we need to define roles, so defining roles, Add this snippet to the .run function in app.js

Here we are defining roles for the anonymous and logged in users. $auth is available via satellizer. Now we need to update the routes code accordingly. Open app.js and update the routes as.

Which means /jokes route will only be available to the users who are logged in.

Also we need to update the menu.html ion-list  as follows:

Also, let’s add the code for logout function in the app.js  run  function as,

Also we can get the current logged in user data with this code snippet. It needs to be added in  app.js  run  function.

This localstorage item is populated when the user logs in.

Now you can run the app, and can see if the user is not logged in we cannot go to /jokes route. Also, if the user is logged in you cannot go back to /auth route.

Adding Pull to refresh functionality

The pull to refresh functionality is very common these days in apps. Like, when we swipe from the top we want to load the new or updated content from the server. For adding pull to refresh, ionic provides a smart directive called ion-refresher . So to use it first we need to add ion-refresher  in our view jokes.html

You can see here on refresh we are calling doRefresh  method, so open the controllers.js and add this method to JokesCtrl as follows,

Now the output will look similar to this,

2015-12-12_19-23-58

Adding Ionic infinite scroll

We would never want our app to load all the data from our server at once. So normally what we do is, we paginate results. For this ionic uses a directive called ion-infinte-scroll . Open the jokes.html and add this directive before the </ion-content>

Now open the controller.js  and replace the init  function with this snippet.

2015-12-12_19-32-39

Here you can see in the console. When we scroll down we are loading the data from the server dynamically.

Wrapping Up Tutorial

If there are any doubts, you can ask in the comments section below.

You can also see this Blog Post, where we have created the API with Laravel5.

Thanks.

Please Consider Donating (Click Here)

  • martin.mildner

    hi baljeet, first of all – thanks for the great tutorials! I am facing a problem at the “securing route” section: In the readme of https://github.com/Narzerus/angular-permission it says “RoleStore.defineRole” and “PermissionStore.definePermission”. You are using “Permission.defineRole” – i am getting the error: Permission.defineRole is not a function!? Any idea?

    In addition: Do you know if it is allowed to use the permission for a abstract state? like this:

    .state(‘app’, {

    url: ‘/app’,
    abstract: true,
    templateUrl: ‘views/main.html’,
    controller: ‘AppCtrl’,
    data: {
    permissions: {
    except: [‘anonymous’],
    redirectTo: ‘login’
    }
    }

    Thanks for your help!!!

    • Hi Martin, library is changed a bit since i have create the article. You can use RoleStore.defineRole instead of Permission.defineRole. I haven’t tried it. But it should work.

      I guess, It should work with abstract state. If you face any issues with the library, you can always create a new issue on github.
      Thanks.

  • Edwin

    hi I keep getting a bad request 400 error from the laravel server what could be the problem?

  • Kaushik Mishra

    how can i pop wrong credentials if i enter wrong user name and password as i’m getting this error from the rest api
    -> http://localhost:8000/api/v1/auth/login 401 (Unauthorized)

  • ricky spires

    Hello. Great tutorials 🙂
    I have an issue with add on ionic. its not working 🙁

    Its working on the previious tutorial.

    I get this in the console.

    add joke: add test
    controllers.js (line 164)
    Error: $rootScope is not defined

    $scope.addJoke@http://localhost:8100/js/controllers.js:168:13

    return logFn.apply(console, args);ionic.bundle.js (line 25642)

    edit and delete work

    ???

    • ricky spires

      Solved.
      $rootScope needs to be added to the JokesCtrl

      .controller(‘JokesCtrl’, function($scope, $auth, $http, $ionicPopup, $rootScope) {

  • Rob Matwiejczyk

    Hey, thanks for the tutorial. Making an api makes so much sense now!

    I’m struggling with the CORS though. I can manage to make GET requests, but whenever I try to POST data I get this error:

    XMLHttpRequest cannot load http://my.app/api/v1/test. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://192.168.1.248:8100’ is therefore not allowed access. The response had HTTP status code 500.

    FWIW, i’m trying to set this up outside of the jwt.auth middleware, as I want to send the users location and return nearby results. I don’t see the need for them to have had to sign up to see how the app works, only when making an order. Could this be the problem?

    • Make sure you have commented the verifycsrf statement in the app/http/kernel.php
      // AppHttpMiddlewareVerifyCsrfToken::class,

      • Rob Matwiejczyk

        Hmmm, still not working. My request looks like this:

        $http({

        url: ‘http://my.app/api/v1/venues’,

        method: “POST”,

        data: {

        latitude: localStorage.getItem(‘latitude’),

        longitude: localStorage.getItem(‘longitude’)

        }

        So currently this goes to the store method due to the resource route. Will be changing that once I get this working, but in that method I’m querying the database for the closest venues. It works fine if I hardcode the lat/long in the VenuesController, but as soon as I try to use the request payload values I get the Access Control error. I don’t understand why 🙁

        • Yur Gasparyan

          ok! its error about cross origin,its happend when you sending request from domain to another domain! if your api have a .htaccess you need to set this code here

          Header set Access-Control-Allow-Origin “*”
          Header set Access-Control-Allow-Headers “Content-type”

      • Rob Matwiejczyk

        Additionally, rather than commenting that out wouldn’t this be the correct way to do it? I already did this before anyway and still the same problem:

        https://github.com/barryvdh/laravel-cors#disabling-csrf-protection-for-your-api

      • Rob Matwiejczyk

        I figured it out. It looks like it was working fine, but i was trying to access the request payload items incorrectly and I think this was breaking the whole thing. Still not sure why i didn’t just get a server 500 error instead of an Access-Control-Allow-Origin error

  • Yur Gasparyan

    hi! please help! what will be response from laravel api ?

  • Yur Gasparyan

    Permision is not defined ..please help

  • مطيع بن عبادة

    Uncaught TypeError: Permission.defineRole is not a function

  • Suwardi Lazzuardi

    I have issue cannot authenticate login, but if I’m running authenticate from rest client my rest api success to authenticate.
    How to catch error in $auth.login(credentials).then(function() { …}) ?

  • Kamakshi

    Hi Baljeet,

    Im getting this error when i was update the permission.defineRole code in the app.js
    Uncaught Error: [$injector:unpr] Unknown provider: PermissionProvider <- Permission

    Please check and let me know the cause of the issue

    • Alex Mercer

      did you managed to fix your issue? I’m experiencing the same issue..

    • Change “Permission” to “PermPermissionStore”

      and

      // Define anonymous role
      PermPermissionStore
      .definePermission(‘anonymous’, function(stateParams) {
      // If the returned value is *truthy* then the user has the role, otherwise they don’t
      // var User = JSON.parse(localStorage.getItem(‘user’));
      // console.log(“anonymous “, $auth.isAuthenticated());
      if (!$auth.isAuthenticated()) {
      return true; // Is anonymous
      }
      return false;
      });

      PermPermissionStore
      .definePermission(‘isloggedin’, function(stateParams) {
      // If the returned value is *truthy* then the user has the role, otherwise they don’t
      // console.log(“isloggedin “, $auth.isAuthenticated());
      if ($auth.isAuthenticated()) {
      return true; // Is loggedin
      }
      return false;
      });

  • Alex Mercer

    Hi, I found your tutorial helpful, but my problem is I am stuck at the permissions, where in my .run should I copy the code snippet? I am still learning Angular and Ionic.. thanks a lot!

  • Paul Kitatta

    Hi, great tutorial. Can you do ionic3?