Phil 2.12.14

Phil 8:00 – 6:30 SR

  • Meeting with Ronda today to discuss progress. We did some paperwork and tried valiantly but in the end unsuccessfully to get keytool working with our new certs.
  • Angular
    • Finished commenting and writing up what I’ve learned about TypeScript and Angular. It’s all in this post on my personal blog.
    • OK, deep breath. Time to get the WebGL code ported from YUI to TS/Angular. Starting with WebGLModulesTest.html, which uses WebGLCanvas.js and WebGLComponent.js.

Dong Shin 02.11.2015

  • working on FR
    • set all initial number to null so that validation works on 0
    • working on adding multiple pocs
      • added new table, point_of_contacts, to database, modified funding_request table
      • added server code
      • adding client

Phil 2.11.14

8:00 – 2:30 SR

  • Alert the media – there are no problems with the production system at all today. no requests, no messages, no nothing.
  • Angular. Need to drill down further into the ramifications of declaring functions using the public/private foo = (arg) =>{}; How does this manifest in EcmaScript6? Does this work with a static declaration? What about typing the return value? For that matter, do these methods inherit properly? I’m going to create a inherit5 file and try these things. In a perfect world, this pattern should collapse the problems with Factory and Directive.
    • EcmaScript 6: The Mozilla Developer Network discusses fat arrows here. The part about ‘lexical this is worth paraphrasing here:
      • Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an “object method”, etc.). This proved to be annoying with an object-oriented style of programming. In ECMAScript 3/5, this issue was fixed by assigning the value in this (e.g. self) to a variable that could be closed over. Arrow functions capture the this value of the enclosing context, so the following code works as expected.
function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();
      • So, according to this and as long as the proposal doesn’t change too much, I think we’re on stable ground
      • Set up Inherit5.html and Inherit5.ts. Pretty much everything works in the ‘best case’ way. The only issue is that Factories and Directives require a function that returns a directive for their initialization. The way to deal with that is to still have the ctor() method, but have it called differently:
      • new AngularMain().doCreate(angular, new InheritApp.TestFactory().ctor,...);
      • This creates an instance (with a this! Yay!), but still allows the angular code to create the directive its way. The full code is here:
  • 3:00 meeting in Hanover.
  • 4:30 class

Phil 2.10.15

8:00 – 4:00 SR

  • Discussed when to update PKIs on the servers with Ronda
  • Deployed a new version of FR for Dong
  • Discussed schedule with Chris
  • Angular,
    • Cleaned up the PasswordDirective to include an IloginObj interface and return types on all the functions inside linkFn() within the BaseLoginDirective class.
    • Working on example large controller
      • The ‘declare var’ trick of keeping TypeScript from complaining is only for external items that you set your local variables equal to. For example, the external Chrome function SpeechSynthesisUtterance  would be defined at the top of the TypeScript file that references as
        • declare var SpeechSynthesisUtterance:any;
      • Later, it gets used as
        • var querySpeech:any = new SpeechSynthesisUtterance();
      • It’s possible to build an interface for it (the entire idea behind definitelyTyped), but this is the way to get up and going quickly.
      • Callbacks have turned into a nightmare. A callback does not have a ‘this’ associated with it when it is called. As such, ANY OTHER MEMBER OF THE CLASS IS NOT AVAILABLE, since this is now ‘Window’ scope. See here for more info.
      • It all has to do with the way that TypeScript has to deal with the self = this problem. To tell TS (and implicitly EcmaScript 6), functions are created using ‘fat arrow’ notation (=>). In any case where you would be using ‘self’ rather than ‘this’ in JavaScript (i.e. nested functions), you need to use the fat arrow notation in TypeScript. In the case of an lambda function, it looks like this:
        • this.querySpeech.onend = (event:Event) => {
             this.queryService.submit(this.query, this.goodUserQuery, this.errorResponse);
          };
      • The generated Javascript looks like this:
        • this.querySpeech.onend = function (event) {
              _this.queryService.submit(_this.query, _this.goodUserQuery, _this.errorResponse);
          };
      • Note that rather than ‘self’ TypesScript has defined ‘_this’. It’s declared as you would expect it.
      • With respect to methods, the pattern in similar. Rather than declaring a method in the ‘default manner:
        • public runQuery(query:string){
             this.query = query;
             this.submit();
          };
      • A method should be declared as follows:
        • public runQuery = (query:string) => {
             this.query = query;
             this.submit();
          };
      • These result in very different JavaScript. The former generates a prototype:
        • QueryController.prototype.runQuery = function (query) {
              this.query = query;
              this.submit();
          };
      • While the latter generates a function that is within the ‘constructor’:
        • this.runQuery = function (query) {
              _this.query = query;
              _this.submit();
          };
      • As you can see, we know how things will work out with a callback in the second function because we’re using _this via closure. With the other JavaScript, things are much less clear – this could be global, or what apply would pass in. Scary.
      • I’m thinking that this way of calling functions is a better way of dealing with factories and directives. I’ll have to try that tomorrow.

Dong Shin 02.10.2015

  • deployed new FR.. few issues found.
  • working on FR
    • fixed Server returning 500 on FR save
    • set maxlength of the input’s to limit the length
    • modified few table columns
    • fixed validations in FR
    • updated Button labels
  • going down the Feedback list
    • moved the ISR PMO button to bottom
    • added Prior Year Req #
    • modified view, appropriations, to exclude the test values
    • set EBC required when funding type is EA or REQ
    • Explanation required when Other is selected in Contract Processing
    • Number of FTEs set to float in Contract Labor and database table
    • Number of FTEs set to float in Government Labor and database table
    • Justification required when Service Fee Amount > 0 in Service Fee
    • FFRDC control by response YES or NO
    • changing all references to Spend Plan to Outlay – client, server, database

Dong Shin 02.06.2014

Phil 2.5.15

8:00 – 6:00 SR

  • Lenny’s using the FR app. So far the only change is that the scheme for saving the project needs to change. Portfolio managers will probably be the last people to touch the submission, so save needs to be supported earlier.
  • Updated my resume to reflect my shiny new MS. I guess it’s a sign of the times, but I have a lot of resumes to update
  • Test TypeScript server access code. If that works, then change the login directive.
  • And it works! I had to change the calling function from this:
(function(angular, queryServicePtr, queryPtr, passwordDialogPtr, undefined) {
   "use strict";
   angular.module('phpConnection', [])
      .factory('QueryService', ['$http', queryServicePtr]);
   angular.module('queryApp', ['phpConnection'])
      .controller('MainCtrl', ['$http', 'QueryService', queryPtr])
      .directive('passwordDialog', ['$http', 'QueryService', passwordDialogPtr]);
})(
   angular,
   globalUtils.appMap.phpFactories.queryServicePtr,
   globalUtils.appMap.queryControllers.queryPtr,
   globalUtils.appMap.passwordDirectives.passwordDialogPtr
);
  • To this JavaScript version…
(function(angular, queryServicePtr, queryPtr, passwordDialogPtr, undefined) {
   "use strict";
   angular.module('phpConnection', [])
      .service('QueryService', ['$http', queryServicePtr]);
   angular.module('queryApp', ['phpConnection'])
      .controller('MainCtrl', ['$http', 'QueryService', queryPtr])
      .directive('passwordDialog', ['$http', 'QueryService', passwordDialogPtr]);
})(
   angular,
   PhpConnectionService.UrlAccess,
   globalUtils.appMap.queryControllers.queryPtr,
   globalUtils.appMap.passwordDirectives.passwordDialogPtr
);
  • And lastly, to TypeScript:
/// <reference path="../../definitelytyped/angularjs/angular.d.ts" />
/// <reference path="../../libs/novetta/services/phpConnectionService.d.ts" />
/// <reference path="../../libs/novetta/directives/PasswordDirectivesTS.d.ts" />

// we do this to accommodate the globalUtils JavaScript object from libs/novetta/globals/globalUtils.js
interface IGlobalUtils{
   appMap:any;
}
declare var globalUtils:IGlobalUtils;

module QueryApp {
   class AngularMain {
      serviceModule:ng.IModule;
      appModule:ng.IModule;

      public doCreate(angular:ng.IAngularStatic,
                  queryServicePtr:Function,
                  queryControllerPtr:Function,
                  passwordDialogPtr:Function){

         this.serviceModule = angular.module('phpConnection', []);
         this.serviceModule.service('QueryService', ['$http', queryServicePtr]);

         this.appModule = angular.module('queryApp', ['phpConnection']);
         this.appModule.controller('MainCtrl', ['$http', 'QueryService', queryControllerPtr]);
         this.appModule.directive('passwordDialog', ['QueryService', passwordDialogPtr]);
      }
   }

   new AngularMain().doCreate(angular,
      PhpConnectionService.UrlAccess,
      globalUtils.appMap.queryControllers.queryPtr,
      PasswordDirectives.BaseLoginDirective.ctor
   );
}
  • That’s it!
  • Now, for completeness, here’s the full TypeScript module with the UrlAccess service:
/// <reference path="../../../definitelytyped/angularjs/angular.d.ts" />

module PhpConnectionService{

   export interface IUrlAccess{
      setPasswordUrl(newUrl:string):void;
      setQueryUrl(newUrl:string):void;
      getPasswordUrl():string;
      getQueryUrl():string;
      submit(query:string, goodResponse:any, errorResponse:any):ng.IPromise<any>;
   }

   export class UrlAccess implements IUrlAccess{
      private passwordUrl:string = 'iopass.php';
      private queryUrl:string = 'io2.php';
      private httpService:ng.IHttpService;

      constructor($http:ng.IHttpService){
         this.httpService = $http;
      }

      static buildParams(obj:any):string {
         var query:string = '';
         var name:string;
         var value: any;
         var fullSubName:string;
         var subName:string;
         var subValue:any;
         var innerObj:any;
         var i:number;

         for(name in obj) {
            if(obj.hasOwnProperty(name)) {
               value = obj[name];

               if(value instanceof Array) {
                  for(i = 0; i < value.length; ++i) {
                     subValue = value[i];
                     fullSubName = name + '[' + i + ']';
                     innerObj = {};
                     innerObj[fullSubName] = subValue;
                     query += UrlAccess.buildParams(innerObj) + '&';
                  }
               }
               else if(value instanceof Object) {
                  for(subName in value) {
                     if(value.hasOwnProperty(subName)) {
                        subValue = value[subName];
                        fullSubName = name + '[' + subName + ']';
                        innerObj = {};
                        innerObj[fullSubName] = subValue;
                        query += UrlAccess.buildParams(innerObj) + '&';
                     }
                  }
               }
               else if(value !== undefined && value !== null) {
                  query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
               }
            }
         }

         return query.length ? query.substr(0, query.length - 1) : query;
      }

      public setPasswordUrl(newUrl:string):void{
         this.passwordUrl = newUrl;
      }

      public setQueryUrl(newUrl:string):void{
         this.queryUrl = newUrl;
      }

      public getPasswordUrl():string{
         return this.passwordUrl;
      }

      public getQueryUrl():string{
         return this.queryUrl;
      }

      public submit(query:string, goodResponse:any, errorResponse:any):ng.IPromise<any> {
         var upstring:string = encodeURI("query=" + query);
         var upObj:ng.IRequestConfig = {
            url: this.getQueryUrl(),
            method: "POST",
            data: upstring,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
         };
         return this.httpService(upObj).then(goodResponse, errorResponse);
      }

      public setPassword(userName:string, userPassword:string, goodResponse:any, errorResponse:any):ng.IPromise<any> {
         var postObj = {query: 'set_password', name: userName, password: userPassword};
         var upObj = {
            url: this.getPasswordUrl(),
            method: "POST",
            data: postObj,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            transformRequest: UrlAccess.buildParams
         };

         return this.httpService(upObj).then(goodResponse, errorResponse);
      }

      public checkPassword(userName:string, userPassword:string, goodResponse:any, errorResponse:any):ng.IPromise<any> {
         var postObj = {query: 'check_password', name: userName, password: userPassword};
         var upObj = {
            url: this.getPasswordUrl(),
            method: "POST",
            data: postObj,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            transformRequest: UrlAccess.buildParams
         };

         return this.httpService(upObj).then(goodResponse, errorResponse);
      }
   }
}
// we do this to accommodate the globalUtils JavaScript object from libs/novetta/globals/globalUtils.js
interface IGlobalUtils{
   appMap:any;
}
declare var globalUtils:IGlobalUtils;
  • So now we have the main calling app done in TS.

Dong Shin 02.04.2014

  • successfully deployed FR!
    • database dump doesn’t have AUTO_INCREMENT, PRIMARY KEY in it…
    • login service returns SUCCESS for invalid login – modified the script to show alert…
  • FMP bugs from Gina?
  • fixed /users/login to return HttpStatus.FORBIDDEN when user is not found
  • going through Spring Tutorial

Dong Shin 02.03.2015

  • deployed new FR stuff – logging work, but login doesn’t!
    • /login goes to SimpleUrlHanderMapping instead of FilterChainProxy
    • copied Phil’s Tomcat config and tried, runs fine….
  • using User object for login – rest/users/login
  • changed login in Services

Phil 2.3.15

8:00 – 5:00 SR

  • Deploying new FR, with debugging. Everything but the login works. Dong is perplexed.
  • More Angular. Working on figuring out how to do complex directives. Huh. The secret is to understand that directives are static. And it turns out that factories are static too.
  • I’ve got my test app now working with
    • a controller
    • a service
    • a directive (with link function)
    • a factory.
  • Next, inheritance on all of the above.
    • Back to TypeScriptEssentials….
    • Modified the command line for the tsc compiler (under ‘watch’). It’s now tsc.cmd –declaration –noImplicitAny –target ES5 –sourcemap <filename>
    • Inheritance works like a charm. Classes with static functions (Factories and Directives) are a bit problematic, since there’s no ‘this’ to refer to. This means that functions are referred to by their fully qualified name (i.e. TestDirective.foo(), rather than this.foo()). Overloading can’t quite work the way that I’d like to. That being said, the static functions do come along for the ride, so as long as all the references are updated, everything works the way it should.

Phil 2.2.15

8:00 – 10:00, 12:00 – 5:30 SR

  • DB backups
  • Worked with Dong to install FR on the test server. The services still aren’t working. Maybe missing jar files?
  • Status report
  • More Angular
    • Tried making factories work but I got stuck trying to access the object’s this. Since they are structured differently but generally have the same functionality(ish), I tried configuring the TypeScript class as a service. That worked just fine – I was able to access public variables and functions through dependency injection.
    • Discovered that the ‘static’ keyword allows for directives to work with classes. THis might also be true for factories. The issue to work through is how the link function connects to the directive. Components like the scatterplot are big directives, and can’t be crammed into a single method in a class.
  • Timesheet!