Sunday, June 26, 2016

Make further proxy requests authenticated

app.get('/hoo/ray', (req,res,next) => {


    let url = "https://www.helloworld.com/ui/fragments/header.html";

    let jar = request.jar();
    let cookie = request.cookie(req.headers["cookie"]);
    jar.setCookie(cookie, url);

    let headers = {cookie};

    request({url, headers}, (error, response, body) => {

        url = "https://www.helloworld.com/ui/fragments/toolbox.html";

        request({url, headers}, (toolboxError, toolboxResponse, toolboxBody) => {

            let html = body + toolboxBody;

            res.writeHead(200, {
                'Content-Type'  : 'text/html',
                'Content-Length': html.length,
                'Expires'       : new Date().toUTCString()
            });


            res.end(html);

        });

    });

});


Next step, convert those callback hell to promises.

Sunday, May 1, 2016

pm2 must not be ran with sudo

If you got an EACCES error when you run pm2 without sudo..

me@ubuntu:~/myapp$ pm2 start ./bin/www
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: connect EACCES /home/me/.pm2/rpc.sock
    at Object.exports._errnoException (util.js:896:11)
    at exports._exceptionWithHostPort (util.js:919:20)
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1073:14)


..chances are you might try to run pm2 with sudo and it will work.

However, it will cause an undefined value on process.env.PWD, and then it will cause SPA page that are refreshed or re-loaded from bookmark not to load.

var base = process.env.PWD;

res.sendFile('index.html', {root: path.join(base, '/public')});


To fix the error, make the following your own file /home/yourUsernameHere/.pm2/rpc.sock

sudo chown yourUsernameHere ~/.pm2/rpc.sock


Doing the above you can now run your pm2 without the sudo.

After running:

$ pm2 start ./bin/www

Run this:

$ pm2 save
$ pm2 startup

Then follow the instruction of that pm2 startup command.


Happy Coding!

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'));
});