Thursday, April 28, 2016

TypeScript productivity

Not only you can do adhoc-y parameters, you can also do adhoc-y return types.


customComplete(dto: { onboardId: number; session: string; }): ng.resource.IResource<{ completed: boolean}>;


Happy Coding!

Naming

Darn, decade (note the singular :P) of experience in the programming industry, and I still don't have a hard and fast rule on names in program like in Firstname vs First Name.

Correct form is First Name, so that gives us these valid names for the program: first_name, firstName, FirstName; words have boundary. Hence these are invalid: firstname, Firstname.

It's a different rule on Username though, correct form is Username, not User Name.These are valid names for the program: username, Username. These are invalid: userName, UserName.

Thursday, April 14, 2016

Refusing deeply nested code

I have this angular directive, and I don't want nested code, so I don't embed the function directly in the link property:

angular.module("AcroformBuilder", [])
    .directive('afBuilder', [() => {
            return <ng.IDirective>{
                restrict: 'E',
                scope: {
                    metaDataGetter: '&',
                    savedDataGetter: '&',
                    afObject: '='
                },
                link: FormBuilder
            };

        }]);

.
.
.
function FormBuilder(scope: IScopeProperties, element: ng.IRootElementService, attrs: ng.IAttributes) {





Eventually, I needed the $q service. Since the link property cannot be dependency injected, the easiest way to solve the problem is to move the function directly to link property. However did I say I refuse deeply nested code? And if you can infer from the code above, directly embedding the function in the directive's link would make the function deeply nested, around 16 spaces or 4 tabs from the left.



To cut to the chase, javascript has this magical function to pass invisible parameter whenever a function is called. That magical function is called bind.

Just bind two parameters, first the object and then the parameter itself. The link's function is called and not instantiated (javascript functions are like a class, can be instantiated too), so we just pass undefined on first parameter and then pass the $q service on the second parameter.

angular.module("AcroformBuilder", [])
    .directive('afBuilder', ['$q',($q: ng.IQService) => {
            return <ng.IDirective>{
                restrict: 'E',
                scope: {
                    metaDataGetter: '&',
                    savedDataGetter: '&',
                    afObject: '='
                },
                link: FormBuilder.bind(undefined, $q)
            };

        }]);

.
.
.
function FormBuilder($q: ng.IQService, scope: IScopeProperties, element: ng.IRootElementService, attrs: ng.IAttributes) {




Happy Coding!

Tuesday, March 29, 2016

Add column with default value and nullity

create table something
(
p int not null
);

insert into something(p) values(1);


alter table something
add q int default 6 not null;


alter table something
add r int default 8 null;


select * from something;



Postgresql output:
p q r
1 6 8



Sql Server output:
p q r
1 6 null

Tuesday, January 12, 2016

First gulp is the best gulp

var gulp = require('gulp');
var ts = require('gulp-typescript');

var tsProject = ts.createProject('theApp/tsconfig.json');


gulp.task('typings', function () {
    return gulp.src('theApp/**/*.d.ts')
        .pipe(gulp.dest('./xdeploy'));
});



gulp.task('genjs', ['typings'], function () {
    return tsProject.src('theApp/**/*.ts')
        .pipe(ts(tsProject))
        .pipe(gulp.dest('./xdeploy'));
});

gulp.task('copyjs',  ['genjs'], function () {
    return gulp.src('theApp/**/*.js')
        .pipe(gulp.dest('./xdeploy'));
});

gulp.task('copyjson',  ['copyjs'], function () {
    return gulp.src('theApp/**/*.json')
        .pipe(gulp.dest('./xdeploy'));
});



gulp.task('default', ['copyjson'], function () {
    return gulp.src('theApp/node_modules/**/*', { 'base' : 'theApp/node_modules' })
        .pipe(gulp.dest('./xdeploy/node_modules'));
});


Friday, October 23, 2015

Alignment problem of Firefox that's non-existent on Chrome

Given this html:

<span class="form-search"></span>
<input class="search-query form-control" style="width: 200px" placeholder="Live search"/>


And CSS:

span.form-search {
    position: relative;       
}
span.form-search:before {
    display: block;
    width: 14px;
    height: 14px;
    content: "\e003";
    font-family: 'Glyphicons Halflings';
    background-position: -48px 0;
    position: absolute;
    top:8px;
    left:8px;
    opacity: .5;
    z-index: 1000;
}
input.search-query {
    padding-left:26px;
}

Live code: https://jsfiddle.net/L1pb9km3/

The above display perfectly ok with Chrome, but not on Firefox.

Chrome:





Firefox:






The work-around to make it work on Firefox is simple, just add a float: left to the span.form-search

span.form-search {
    position: relative;   
    float: left;    
}

Live code: https://jsfiddle.net/axjk3xss/

Yes it's easy to land on comet than to properly align stuff on web using CSS.

Tuesday, October 20, 2015

Can't set the $pristine on constructor

Let's say you are using a directive that has problem with pristine, i.e., on first load the aForm is already dirty:

<form name="c.aForm">
<someDirectiveWithBugHere></someDirectiveWithBugHere>
</form>

<div>{{c.aForm.$pristine}}</div>




You can't set the aForm to pristine on constructor, as aForm is not yet defined while on constructor:
module App.UserEdit
{
    export class MainController
    {
        aForm: ng.IFormController;

        constructor(public Resources: InhouseLib.Resources)
        {
             this.aForm.$setPristine();

        }
    }
}

Setting the form to pristine while on constructor would give this result:
TypeError: Cannot read property '$setPristine' of undefined
    at new MainController

A work-around is to set the pristine state after the form is loaded, and by calling the expression (that will set the pristine to clean) on ng-init:
<form name="c.aForm">
<someDirectiveWithBugHere></someDirectiveWithBugHere>
</form>
<div ng-init="c.setClean()"></div>

<div>{{c.aForm.$pristine}}</div>

Remove the $setPristine from the controller and move it to setClean:
module App.UserEdit
{
    export class MainController
    {

        aForm: ng.IFormController;

        constructor(public Resources: InhouseLib.Resources)
        {
        }
    
        setClean(): void
        {
            this.aForm.$setPristine();
        }
    }
}


Or if you don't want the controller to have concerns on those stuff, you can initialize the form's state directly on html.

<div ng-init="c.aForm.$setPristine();"></div>

<div>{{c.aForm.$pristine}}</div>