Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How I Created an AngularJS/MySQL TODO App in 0.649 Seconds

DZone's Guide to

How I Created an AngularJS/MySQL TODO App in 0.649 Seconds

In this post, we explore how one developer was able to create an application that enables super fast Angular development.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

In the next release of Hyper IDE, there will be an ORM library for MySQL called Hyper Core. This library is built upon HTTP REST services, returning JSON to the client, allowing you to do stuff like the following:

/hyper-core/mysql/database/table/select?[limit]=25

The above will select the first 25 records, from your "database" database, and its "table" table. You can also further refine your query, with any criteria you wish to decorate your SQL with, using additional HTTP query parameters. Hyper Core also contains REST endpoints for "insert," "update," and "delete" - and, hence, becomes a complete ORM library for front-end clients. Since each database, table, and operation gets its own unique URL, this allows you to easily grant or deny access to tables and operations, according to the URL for the [database]/[table]/[operation].

In addition, I have been working extensively with Hyper IDE, on which I have written several other articles. One of the additions I have created to Hyper IDE is a new "template project type" for AngularJS developers, which will create all the boilerplate code for an AngularJS "TODO" app, which ties into the server-side backend, using Hyper Core, and even automatically creates a database for you. This allows you to start out a new AngularJS project literally "running," having a great foundation for not only your main AngularJS front-end code but also having solved most of your backend needs. Using the above features, I was able to create the following app, in 0.649 seconds.

Image title

In this video, I demonstrate how I created this application, arguably in 0.649 seconds. Needless to say probably, but I think this would be highly valuable for any new AngularJS projects you want to create, while also solving most of your database backend needs, assuming you want to build it upon MySQL. You can see the auto-generated code here (expand the "/modules/todo/" folder).

If you want to test this as of today, you'll have to fork the repositories, since I still haven't bundled this up in a release yet. Below you can see the autogenerated Angular HTML code.

<!doctype html>
<html ng-app='todoApp'>
  <head>
    <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js'></script>
    <script src='modules/todo/controller.js'></script>
    <link rel='stylesheet' type='text/css' href='/modules/micro/media/main.css' />
    <link rel='stylesheet' type='text/css' href='/modules/micro/media/skins/serious.css' />
    <link rel='stylesheet' type='text/css' href='modules/todo/styles.css' />
  </head>
  <body>
    <div class='container'>
      <div class='row'>
        <div class='col'>
          <div ng-controller='TodoListController as todoList' class='shaded air-inner bg rounded'>
            <h1>Todo</h1>
            <form ng-submit='todoList.addTodo()'>
              <div class='new-item strip'>
                <input type='text' autocomplete='off' ng-model='todoList.todoText' placeholder='Add item ...' id='newItem'>
                <input type='submit' class='submit-button' value='add'>
              </div>
            </form>
            <div>
              <ul class='todos'>
                <li ng-repeat='todo in todoList.todos' ng-click='todoList.delete(todo.id)'>{{todo.description}}</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

If you don't know much AngularJS, it's important to know that the above code creates a single "form," which invokes our controller's "addTodo" function when submitted. In addition, it creates an Angular "repeater," which will create one "li" element for each item in our "todoList.todos," which is declared in our controller. When the "li" element is clicked, it will invoke our controller's "todoList.delete()" function, passing in the database id of the item that was clicked. Below you can see the controller file for our module.

/*
 * Main module for our Angular app.
 */
angular.module ('todoApp', [])

  /*
   * Our only controller, responsible for invoking our server side back end,
   * and databinding our view.
   */
  .controller ('TodoListController', function ($scope, $http) {

    /*
     * Fetching existing items from our server.
     */
    var todoList = this;
    $http.get ('/hyper-core/mysql/todo/items/select?[limit]=50').
      then (function successCallback (response) {
        todoList.todos = response.data;
    });

    /*
     * Invoked by our view when a new item has been added by user.
     * Invokes the MySQL server-side back end, and inserts the newly inserted
     * item into our "view".
     */
    todoList.addTodo = function () {

      /*
       * Invoking our server-side method, to insert item into our database.
       *
       * Notice, server-side back end requires a 'PUT' request for our 'insert' method.
       *
       * The URL we use is in the format of '/hyper-core/mysql/[database]/[table]/[operation]'.
       */
      $http ({
        method:'PUT', 
        url: '/hyper-core/mysql/todo/items/insert', 

        /*
         * Our server-side requires the data for our insert operation to be URL encoded,
         * hence we'll need to transform from the default serialization logic of Angular,
         * which is JSON, to URL encoded data.
         */
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        transformRequest: function (obj) {
          var str = [];
          for (var p in obj) {
            str.push (encodeURIComponent (p) + '=' + encodeURIComponent (obj [p]));
          }
          return str.join ('&');
        },
        data: {description: document.getElementById ('newItem').value}
      }).then (function successCallback (response) {

        /*
         * Pushing our new item into our list of items, and making sure
         * we set our textbox' value to empty.
         */
        todoList.todos.push ({
          description: todoList.todoText, 
          id:response.data.id
        });
        todoList.todoText = '';
      });
    };

    /*
     * Invoked by our view when an item is deleted.
     */
    todoList.delete = function (id) {

      /*
       * Deleting our clicked item from our list of items from our view.
       */
      for(var idx = 0; idx < todoList.todos.length; idx++) {
        if (todoList.todos [idx].id === id) {
          todoList.todos.splice (idx,1);
          break;
        }
      }

      /*
       * Invoking our server-side method, to delete item from our database.
       *
       * Notice, server-side back end requires a 'DELETE' request.
       */
      $http.delete('/hyper-core/mysql/todo/items/delete?id=' + id);
    }
  });

Now I want to emphasize that there are no good reasons for you to start copying and pasting this code into your own projects since it was auto-generated in 0.649 seconds while creating a new "angular-todo" app using Hyper IDE. However, the semantics of our above controller might be interesting to analyze.

Initially, it selects the first 50 items from our MySQL todo.items database and table, using an HTTP GET request towards Hyper Core. Then it uses the automatic databind features from AngularJS to databind this to our "ul" element in our HTML page. In addition, it creates an "addTodo" function, which inserts a new item into our database, using an HTTP PUT request, and a "delete" function, which deletes an item from our database using an HTTP DELETE request.

Yet again, since each of these operations gets unique URLs, and also each database/table ends up having a unique URL, this allows us to create very fine-grained access controls for who is allowed to do what towards our data. If you would like everybody to only read from the database, for instance, but only "super-user" roles to create, update, and delete items, you could use the Peeples module in Phosphorus Five to assign access rights with something resembling the following.

*
  p5.module.allow:/modules/todo/
*
  p5.module.allow:/modules/hyper-core/
*
  p5.hyper-core.allow:/hyper-core/mysql/todo/items/select
super-user
  p5.hyper-core.allow:/hyper-core/mysql/todo/items

The above would assign read access to everybody on the "todo.items" database/table, by allowing everybody to perform a "select" operation toward your MySQL database, while only a user belonging to the role of "super-user" would be allowed to use all four verbs toward the same database. In my example online application, I have assigned access to all four verbs to everybody. You can try the app here. You can also see the code in my example server's Hyper IDE's installation, from where you must expand the "/modules/todo/" folder to browse the code.

And in fact, if you copy the content of the HTML page into another HTML page in the "/test/" folder in my Hyper IDE example server, you can even modify the code yourself online, in my Hyper IDE installation. I demonstrate the latter in this video.

Disclaimer - For the record, I will periodically *delete* the contents of the "/test/" folder on my server, so don't expect your code to live there forever. Also, be careful with running other people's code, as I have no control over what they might have put into their HTML or JavaScript file(s). However, yes, basically, as long as everybody is nice, I'll basically allow you to play around with my AngularJS/MySQL sample, online, on my own private server, to create your own AngularJS app, which integrates towards my MySQL "todo.items" database/table any way you see fit. My suggestion to you if you do, is to create some new folder, with a "weird name," and put your code inside of that folder. This reduces the possibility that somebody else will tamper with your files, as you're testing it yourself.

Homework - Can you figure out how to modify the app to perform an "update" operation? The server grants you these right, but only on the "todo.items" database/table.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
angular ,mysql ,angularjs ,web dev

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}