Lab 8 (Legacy)

Be sure to get enough REST

Now you are going to expand upon your work from the previous lab. This is going to require the following components:

The REST interface

I'm purposefully leaving some of the REST interface details vague so you can decide how to implement them yourself. I recommend the following sort of thing:

This will be implemented by your node server which you will run by typing some variation on node myserver.js. I'm choosing to call my server express.js

For example, here is a slimmed down version of express.js. I have removed functional details in order to let you add those back in. I implemented this version without Promises or connectionPools, but you probably want to to add those in. The repository ONLY has a stub.

var express=require('express'),
mysql=require('mysql'),
credentials=require('./credentials.json'),
app = express(),
port = process.env.PORT || 1337;

credentials.host='ids.morris.umn.edu'; //setup DATABASE credentials

var connection = mysql.createConnection(credentials); // setup the connection

connection.connect(function(err){if(err){console.log(error)}});

app.USE(express.static(__dirname + '/public'));
app.get("/buttons",function(req,res){
  var sql = 'SELECT * FROM test.till_buttons';
  connection.query(sql,(function(res){return function(err,ROWS,fields){
     if(err){console.log("We have an error:");
             console.log(err);}
     res.send(rows);
  }})(res));
});
app.get("/click",function(req,res){
  var id = req.param('id');
  var sql = 'YOUR SQL HERE'
  console.log("Attempting sql ->"+sql+"<-");

  connection.query(sql,(function(res){return function(err,ROWS,fields){
     if(err){console.log("We have an insertion error:");
             console.log(err);}
     res.send(err); // Let the upstream guy know how it went
  }})(res));
});

app.listen(port);

The angular template

You have done the tutorials (and many of you have worked with angular in other classes), so I'll just provide a sample of the sort of thing that I used to implement "clickability" on the item buttons (note: I did NOT add the css file that I used):

<!doctype html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <title>Cash Register</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.MIN.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.MIN.js"></script>
    <script src="click.js"></script>
</head>
<body ng-app="buttons">
<div class="container-fluid">
    <h1>Cash Register (WITH buttons)</h1>
    <div id="buttons" ng-controller="buttonCtrl" >
       <div ng-REPEAT="button IN buttons">
         <div style="position:absolute;LEFT:{{button.LEFT}}px;TOP:{{button.TOP}}px"><button id="{{button.buttonID}}" ng-click="buttonClick($EVENT,'button.buttonID');" >{{button.label}}</button></div>
       </div>
       <div style="position:fixed;height:50px;bottom:0px;LEFT:0px;RIGHT:0px;margin-bottom:0px"} ng-SHOW="errorMessage != ''">
          <div class="col-sm-12">
           <h3 class="TEXT-danger">{{errorMessage}}</h3>
         </div>
       </div>
     </div>
</div>
</body>
</html>

The JavasScript

You will notice that the Angular template loads a javascript file named click.js (which I have included in the public subdirectory). Most of this is boiler plate material... but notice how we use $scope. to make functionality defined in click.js available in our web-page.

angular.module('buttons',[])
  .controller('buttonCtrl',ButtonCtrl)
  .factory('buttonApi',buttonApi)
  .constant('apiUrl','http://146.57.34.125:1337'); //CHANGE FOR the lab!

function ButtonCtrl($scope,buttonApi){
   $scope.buttons=[]; //Initially ALL was still
   $scope.errorMessage='';
   $scope.isLoading=isLoading;
   $scope.refreshButtons=refreshButtons;
   $scope.buttonClick=buttonClick;

   var loading = false;

   function isLoading(){
    return loading;
   }
  function refreshButtons(){
    loading=true;
    $scope.errorMessage='';
    buttonApi.getButtons()
      .success(function(data){
         $scope.buttons=data;
         loading=false;
      })
      .error(function () {
          $scope.errorMessage="Unable to load Buttons:  DATABASE request failed";
          loading=false;
      });
 }
  function buttonClick($EVENT){
     $scope.errorMessage='';
     buttonApi.clickButton($EVENT.target.id)
        .success(function(){})
        .error(function(){$scope.errorMessage="Unable click";});
  }
  refreshButtons();  //make sure the buttons are loaded

}

function buttonApi($http,apiUrl){
  return{
    getButtons: function(){
      var url = apiUrl + '/buttons';
      return $http.get(url);
    },
    clickButton: function(id){
      var url = apiUrl+'/click?id='+id;
//      console.log("Attempting WITH "+url);
      return $http.get(url); // Easy enough to DO this way
    }
 };
}

For this week's lab I would like you to add the following functionality:

You can look at my online example, to see what I'd like you to aim for.

Also be certain that you create a document detailing your API (include this in your repository) as well as your group members and database.

If you totally nail this you can begin preparing for next week by adding the ability to