javascript statement completion value

We all know how painful it is to write long and tedious cloud formation json templates. Cloudform is a nice little library to write cloud formation template in typescript and will compile it into json. Its types are all from amazon’s own library so it is easy to keep up to date without the maintainer having to write new code to support the new aws features.

As I was reading the source code of cloudform compiler where it eventually emit the cloud formation template via a eval() function, i was kind of confused how it works. As i dig deeper, find an interesting concept in js that I never heard of: statement completion value.

To test that, i did some test on the node cli:

const s0 = 'const f1 = ()=>1;';
const s1 = 'const f1 = ()=>1; f1();';
const s2 = 'const f1 = ()=>1; f2 = ()=>2; f1(); f2()';
const s3 = 'const f1 = ()=>1; f1(); "2"';

// output undefined
// output 1
// output 2
// output 2

So this means, it always take the last valid return value.

Another note is IIFE can also return value as long as you have return statement. And async is not well supported as the eval is executed synchronously, so logic executed in other ticks will not get a chance to return unless we do some monkey patching with async/await.

interesting reference on question by Paul Irish on Twitter on 01/2017 and answered by Brendan Eich: HERE


package json bin field

We can define some executable js file in the bin section of the package json so that during installation, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.

The file js need to start with the node flavor hash ban : #!/usr/bin/env node,  where the env will file the path of node in the system for us.

And npm will also add the ./node_modules/.bin into the PATH for its script section so if we define something like `{ “bin” : { “myapp” : “./cli.js” } }`. Then in the `script` we just need to define:

run-myapp: myapp. rather than run-myapp: ./node_modules/.bin/myapp.

debug nodejs in chrome

The new chrome ships with the about:inspect and a dedicated debugger for nodejs which is super cool! At least we do not have to rely solely on console.log() magic.

To do that, run script with an additional flag:

node --inspect myServer.js

This should fire up the app and then go to a new tab and enter about:inspect. Then click on the open dedicated DevTools for Node link, which opens a debugger for node. Now you can start to put break points etc…

More options HERE and a video intro.

npm dev dependency not installed

When running npm install, the dev dependencies are usually also get installed. However today, we have a build runs inside a docker container which requires a test result to be generated and we cannot get test run. Turns out the Karma packages in the dev dependencies are not installed.

The reason is the container in which npm is run has a NODE_ENV environment var set to production so npm will pick that up and skip the dev dependencies installation.

Other scenarios dev will not be installed is

1. the npm config production value is set to true. use below command to check.

npm config get production

2. npm is run with --production flag.


So to solve this, we just unset that var and set it back after npm install.

unset NODE_ENV

npm install

export NODE_ENV=production

exclude file from karma coverage report

We have some files that is not so testable (like animation related, or things like polyfills) to be excluded from the karma coverage report. With angular-cli looks like it is straightforward that we can include the below config:

 "test": {
    "codeCoverage": {
      "exclude": [
    "karma": {
      "config": "./karma.conf.js"

However since we are not using cli , we need to tweak ourselves. Found the PR that implements the above feature. Looks like we just need to push the files to be excluded to the webpack config’s module rules for istanbul-instrumenter-loader`. Something like:

 rule: [
        enforce: 'post',
        test: /\.(js|ts)$/,
        loader: 'istanbul-instrumenter-loader',
        include: helpers.root('src'),
        exclude: [
          // add files needs to be excluded from coverage report below

The helpers.root is just a help function get get the proper path.

function root(args) {
  const path = require('path');
  args =, 0);
  const ROOT = path.resolve(__dirname, '..');
  return path.join.apply(path, [ROOT].concat(args));

In the coverageReporter of karma.conf.js, we can set a lot of useful things like threshold, dir(normalized with subdir), etc…

execute async call sequentially

fix number of calls

Today, i need to figure out a way to execute a bunch of http call sequentially. The problem first looks simple if we have known number of calls so that we can easily put them in callback one by one or chain the promise.


 .then(() => {
  return call2();
  return call3();

number of calls varies

However if what we get is an array with any number of calls, it becomes tricky. the above aways obviously does not work.

promise holder with IIFE

One way is to define a promise out of the for loop, and assign the promise returned by the previous promise to it.

let itemsToProcess = [...]
let promiseHolder = processItem(itemsToProcess[0]);
for (let i = 1; i < itemsToProcess.length; i++) {
    (function() {
        let thisItem = itemsToProcess[i];
        let getNewPromise = () => processItem(thisItem);
        promiseHolder = promiseHolder.then(res => {
            return getNewPromise();

Or use reduce function to rescue:

let itemsToProcess = [...]
itemsToProcess.reduce((lastPromise, item) => 
 lastPromise.then(() => 
 ), Promise.resolve()

async and await

a more elegant way is to use the async and await inside for loop which will auto block the execution and wait.

for (let item of itemsToProcess) {
    let rs = await processItem(browser, item);

Yes, the code is this simple. The introduction of async/await from node7.x+ is really useful. await suspends the current function evaluation, including all control structures.

Caveat with foreach/map

One caveat is be very careful use async in the forEach/map loop, it would not work as expected if what you want is serial.

itemsToProcess.forEach(async (item)=> {
    let rs = await processItem(browser, item);

Rather than waiting for execution one by one, all the async call will fire at the same time. forEach expects synchronous function. Think about it this way: an async function returns a promise and it’s the caller’s responsibility to do something with that promise. However, Array#forEach doesn’t do anything with the return value of the callback, it simply ignores it. All it does is call the callback for each element. The Promise.all([...myPromiseArray]) will behave similar because promise is hot that the time it is created, the xhr/event is already fired.

one way is to create a forEachAsync to help but basically use the same for loop underlying.

Array.prototype.forEachAsync = async function(cb){
    for(let x of this){
        await cb(x);

A good video about async/await

angular change detection notes

Was reading some angular change detection related articles trying to understand it. some note.

Angular can detect when component data changes, and then automatically re-render the view to reflect that change.


ngZone is an angular verison of zone.js, which patches the browser async calls like user event(click/keyup etc), settimeout/interval, XHR.  It is similar to the AOP we have in Spring that proxies are created by framework to do before/after custom logic around the original method call. The importance of this angular patch these brower-API to trigger the change-detection. Previously in ng1, we have all those special directives like ng-click, $timeout etc to make sure after all the custom logic is done, we all the angularjs $apply() to run the digest cycle to do the dirty check and update the view if necessary. Now in ng2+, all these special stuff are gone because of the usage of Zone which enables us to fire change detection after any of these browser event are done from the main stack. Here is a good article explaining zone in angular.

Basically, The short version is, that somewhere in Angular’s source code, there’s this thing called ApplicationRef, which listens to NgZones onStable event. Whenever this event is fired, it executes a tick() function which essentially performs change detection.

  tick() {
      .forEach((ref) =&amp;gt; ref.detectChanges());

change detection flow

So now we know how CD is triggered, now time for how it is executed.

change detector classes are created on the fly by angular for each component.

From the top of the component(view) tree, we start the CD.

The main logic responsible for running change detection for a view resides in checkAndUpdateView function. Most of its functionality performs operations on child component views. This function is called recursivelyfor each component starting from the host component. It means that a child component becomes parent component on the next call as a recursive tree unfolds.

When this function triggered for a particular view it does the following operations in the specified order:

  1. sets ViewState.firstCheck to true if a view is checked for the first time and to false if it was already checked before
  2. checks and updates input properties on a child component/directive instance
  3. updates child view change detection state (part of change detection strategy implementation)
  4. runs change detection for the embedded views (repeats the steps in the list)
  5. calls OnChanges lifecycle hook on a child component if bindings changed
  6. calls OnInit and ngDoCheck on a child component (OnInit is called only during first check)
  7. updates ContentChildren query list on a child view component instance
  8. calls AfterContentInit and AfterContentChecked lifecycle hooks on child component instance (AfterContentInit is called only during first check)
  9. updates DOM interpolations for the current view if properties on current view component instance changed
  10. runs change detection for a child view (repeats the steps in this list)
  11. updates ViewChildren query list on the current view component instance
  12. calls AfterViewInit and AfterViewChecked lifecycle hooks on child component instance (AfterViewInit is called only during first check)
  13. disables checks for the current view (part of change detection strategy implementation)

Some lifecycle hooks are called before the DOM update (3,4,5) and some after (9). So if you have the following components hierarchy: A -> B -> C, here is the order of hooks calls and bindings updates:

A: AfterContentInit
A: AfterContentChecked
A: Update bindings
    B: AfterContentInit
    B: AfterContentChecked
    B: Update bindings
        C: AfterContentInit
        C: AfterContentChecked
        C: Update bindings
        C: AfterViewInit
        C: AfterViewChecked
    B: AfterViewInit
    B: AfterViewChecked
A: AfterViewInit
A: AfterViewChecked

check on reference

By default, Angular Change Detection works by checking if the value of template expressions have changed. This is done for all components. In other word, Angular does not do deep object comparison to detect changes, it only takes into account properties used by the template.


Ng2+ gets rid of the ng1 way of doing dirty check which would result in multiple rounds of check. Now we only have 1 round. If we change the fields in the life cycle hooks like ngAfterViewChecked, we will get xxx has changed after it was checked. This error message is only thrown if we are running Angular in development mode. In production mode, the error would not be thrown and the issue would remain undetected.

trigger CD manually

There could be special occasions where we do want to turn off change detection. Imagine a situation where a lot of data arrives from the backend via a websocket. We might want to update a certain part of the UI only once every 5 seconds. To do so, we start by injecting the change detector into the component:

constructor(private ref: ChangeDetectorRef) {
    setInterval(() =&amp;gt; {
    }, 5000);

As we can see, we just detach the change detector, which effectively turns off change detection. Then we simply trigger it manually every 5 seconds by calling detectChanges().


Some references:

  1. How does Angular Change Detection Really Work ?
  3. Everything you need to know about change detection in Angular

some other good article in angularInDepth:

Exploring Angular DOM manipulation techniques using ViewContainerRef

The mechanics of DOM updates in Angular

difference between detechChanges and markForCheck