Tuesday

Javascript waiting on multiple asynchronous calls

The sample code shows you how to use JQuery when().done() so that web client can wait for multiple AJAX async calls before acting on it.
The button on the following html fires off two calls. The result won't display until both AJAX asynchronous calls return. Put all three files in the same folder to test.
async_index.html:

service1.html:

service2.html:


Friday

How to pass authentication token to AngularJS component


AngularJS is so popular nowadays. Most likely you are already using or want to. An interesting question is when you integrate Angular components into existing secured web app, how do you secure you Angular components. Note that these UI components may be sending HTTP request to a different server than existing ones. One common approach is to pass security token from existing web page to the new Angular components, which is then passed over onto server side for security checks. This article uses a demo app to explain the solution. Complete working code samples can be found in my GitHub

Download all files into the same web folder of your test server. I like to use browser-sync. Follow the link to learn how to use browser-sync. It helps you to understand better if you run the demo app while reading.

Index.html: This is the starting point of the sample web app. Assume you have an existing credit card  web app on which there is already a login button. And you want to add a new set of features like credit card notification features, using secured AngularJS components. You want your customers to login and manage notification preferences.


In the login() method of index.html, you use 
sessionStorage.setItem('token', 'ABCDE');
to store the authentication token obtained from server side, which is displayed on page for purpose of demo.

After login, customer clicks "Continue to Notification Center after login", which opens up Notification.html. It contains Angular app called "app".


The Angular app is defined in app.js. prefController initialization also defines available notification types, which is for demo purpose. Note how it gets token from session storage:
$scope.token = $window.sessionStorage.getItem('token');


It also includes 'pref' directive, defined by "granularpref.html":


where customer's notification preferences are mapped to model pref.optIn.

Upon submit, the preferences are saved by function 'savePref()', which is only for demo purpose. The key take away is that you use $window to pass value into Angular controller, and read token stored in sessionStorage and store in $scope, as displayed on the page (see {{token}} in granularpref.html. In real world, you would send this token to backend for authentication. 

Wednesday

Testing in multiple browsers using browser-sync

The following instruction describes how to use browser-sync to test web code in multiple browsers, with the ability to detect code changes residing in a directory, including all sub-directories recursively.

  • Download and install Node.js
  • Open DOS command window and run 
    npm install -g browser-sync
  • Go to your parent directory underneath which HTML (CSS and javascript) files are located
  • Run 
    browser-sync start --server --directory --files "**/*.*"
  • This will start up a mini web server at default port and launch default browser window, e.g. Chrome. "--directory" means directory list helping you to naviage to files.
  • Click folder or HTML files to open the page you want to test
  • Optionally, if you want to test a different type of browser (e.g. FireFox) at the same time, open FireFox and copy paste the same url
  • Make code change in your editor and save
  • Watch both browsers automatically refresh to test your changes!!!
Happy coding!

Monday

Sorting results when using TopLink ObjectLevelReadQuery conformresultsinunitofwork()

This article explains odd TopLink behaviors when  sorting query results that includes both in memory as well as persistent data from database.

As you know, conformresultsinunitofwork enables the query to merge results from database with those in-memory objects. For instance, the following data exist in EMPLOYEE table:
name                type
-----              ------
employee 1    contractor
employee 2    contractor

And in the session of the same transaction, there are newly created Employee objects "emplyee 3" and "emplyee 4", also contractors. If we want to find all the contractor employees including the ones in the memory, we should use conformresultsinunitofwork(), and the query result will be:
"employee 3"
"employee 2"
"employee 1"
"employee 4"

If the query result is sorted by name, like
ExpressionBuilder builder = new ExpressionBuilder();
query.addOrdering(builder.get("name").ascending());

You would expect that the result be:
"employee 1"
"employee 2"
"employee 3"
"employee 4"

You are wrong! The end result is not actually sorted!!! TopLink will actually just send the query to Oracle
server, which executes it and sorts the result by name, then TopLink will again add the in-memory objects on the top of collection returned from database:
"employee 3" (in-memory)
"employee 4" (in-memory)
"employee 1" (from DB)
"employee 2" (from DB)

Note that the in memory objects are not sorted at all, but the ones from DB are. The reason it behaves like this, is that Oracle server has no idea about the newly created objects. The solution is to just implement the query without sorting, and then sort results in memory using Java. Just remember that you don't sort it twice: once in Oracle server and once in your Java code.