Google

Oct 1, 2013

Angular JS Questions and Answers

Q. How will you display different images based on the status being red, amber, or green?
A. Use the ng-switch and ng-switch-when directives as shown below.


<div ng-switch on="account.status">
 <div ng-switch-when="AMBER">
  <img class="statusIcon"
   src='apps/dashboard/amber-dot.jpg' />
 </div>
 <div ng-switch-when="GREEN">
  <img class="statusIcon"
   src='apps/dashboard/green-dot.jpg' />
 </div>
 <div ng-switch-when="RED">
  <img class="statusIcon"
   src='apps/dashboard/red-dot.jpg' />
 </div>
</div>


Q. How will you initialize a select box with options on page load?
A. using the ng-init directive.

<div ng-controller="apps/dashboard/account" ng-switch
 on="!!accounts" ng-init="loadData()">


Q. How will you show/hide buttons and enable/disable buttons conditionally?
A. Using the ng-show and ng-disabled directives.

<div class="dataControlPanel"
    ng-show="accounts.releasePortfolios">
    
    <div class="dataControlButtons">
     <button class="btn btn-primary btn-small"
      ng-click="saveComments()" ng-disabled="disableSaveButton">Save</button>
     <button class="btn btn-primary btn-small"
      ng-click="releaseRun()" ng-disabled="disableReleaseButton">Release</button>
    </div>
</div>


Q. How will you loop through a collection and list each item?
A. Using the ng-repeat directive.

<table
  class="table table-bordered table-striped table-hover table-fixed-head portal-data-table">
  <thead>
   <tr>
    <th>account</th>
    <th>Difference</th>
    <th>Status</th>
   </tr>
  </thead>
  <tbody>
   <tr
    ng-repeat="account in acounts">
    <td width="40%">{{account.accountCode}}</td>
    <td width="30%" style="text-align: right">{{account.difference
     | currency: ""}}</td>
    <td width="30%">

     <div ng-switch on="account.status">
      <div ng-switch-when="AMBER">
       <img class="statusIcon"
        src='apps/dashboard/amber-dot.jpg' />
      </div>
      <div ng-switch-when="GREEN">
       <img class="statusIcon"
        src='apps/dashboard/green-dot.jpg' />
      </div>
      <div ng-switch-when="RED">
       <img class="statusIcon"
        src='apps/dashboard/red-dot.jpg' />
      </div>
     </div>

    </td>
   </tr>
  </tbody>
</table>


Q. How will you add options to a select box?
A. Using the ng-options and ng-model directives.

<fieldset>
 <dl class="control-group">
  <dt>
   <label for="cientId">
    <h4>Client Id:</h4>
   </label>
  </dt>
  <dd>
   <select id="cientId" class="input-xlarge" ng-model="clientId"
    ng-options="reportClient.clientId as reportClient.clientId  for reportClient in reportClients "
    ng-click="getReportParams()" ng-change="getValuationDates()" />
  </dd>
 </dl>
 <dl class="control-group">
  <dt>
   <label for="valuationDate">
    <h4>
     Valuation Date <small>(dd/mm/yyyy)</small>
    </h4>
   </label>
  </dt>
  <dd>
   <select id="valuationDate" class="input-xlarge"
    ng-model="valuationDate"
    ng-options="reportdate for reportdate in reportDates" />
  </dd>
 </dl>
</fieldset>

Q. How will you display inprogress revolving image to indicate that RESTful data is bing loaded?
A.
<div ng-show="loading">
 <img class="loading" src="portal/images/loading_32.gif" />
</div>


   $scope.loadReportData = function($http) {
  $scope.loading = true;  // start spinng the image
  $http(
    {
     method : 'GET',
     url : propertiesService.get('restPath')
       + '/myapp/portfolio/'
       + $scope.clientId
       + '/'
       + dateService
         .userToRest($scope.reportDate),
     cacheBreaker : true
    }).success(
    function(data, config) {
     $scope.reportData = data;
     portal.log('reportData: ',
       $scope.reportData);
     $scope.loading = false;   // stop spinning the image
    }).error(
    function(data, status, headers, config) {
     if(data.errorMsg != null) {
      $scope.httpError = data.errorMsg;
     }
     else {
     $scope.httpError = "Error retrieving data from " + errorService
       .getApacheErrorTitleMessage(status,
         data, config);
        }
     $scope.loading = false;  // stop spinning the image
    });

 };




Labels:

Sep 18, 2013

AngularJS communicating between controllers



The previous posts covered  AngularJS big picture : Overview and  Working with Angular JS and jQuery UI : writing a custome directive. Let's look at inter controller communication in this blog post.

Q. How do you communicate between controllers in AngularJS?
A. There are scenarios where you want to communicate between controllers. For example, when the submit button is clicked on the parent controller, some values need to be passed to the child controller to show or hide a button in the child form. In AngularJS you can do this with $watch and $broadcast on the parent controller and $on on the child controller.


$watch(watchExpression, listener, objectEquality) : Registers a listener callback to be executed whenever the watchExpression changes.

$broadcast(name, args) : Dispatches an event name downwards to all child scopes (and their children) notifying the registered ng.$rootScope.Scope#$on listeners.

Here is the sample code:


   $scope.buttonClicked = 'N';

   //invoked when $scope.buttonClicked value changes
   $scope.$watch('buttonClicked', function(message) {
  //pass val = 'Y'
  if (message != null) {
   $scope.$broadcast('buttonClicked', {
     "val" : message
   });
   $scope.buttonClicked = 'N';
  }
 });
 
 //when submit button is clicked
 $scope.onParentSubmitButtonClick = function() {
  $scope.buttonClicked = 'Y';
  if ($scope.clientId && $scope.valuationDate) {
   $scope.httpError = null;
    $scope.getCalcStatuses();
   } else {
    $scope.httpError = "Client id or valuation date can not be empty !!";
   }

 };
    


Now, in the child controller, you want to pass the value "val" to indicate that "submit" button has been clicked. "$scope.$broadcast" invokes $scope.$on on the child controllers.

  $scope.$on('buttonClicked', function(event, args) {
  if (args.val == 'Y') {
   $scope.filterText = null;
  }
   
  $timeout(function() {
   $scope.isReleasable(); 
   $scope.isSavable();
          console.log('update with timeout fired');
     }, 2000);
     
  $scope.isReleasable = function() {
   if ($scope.calcViewStatuses != null) { 
    if ($scope.calcViewStatuses.ragStatus == 'GREEN' && $scope.calcViewStatuses.releaseStatus != 'RELEASED') {
     $scope.showReleaseButton = true;
     } else {
     $scope.showReleaseButton = false;
    }
   }
  };
    
    
  $scope.isSavable = function() {
   if ($scope.calcViewStatuses != null) { 
    if ($scope.calcViewStatuses.releaseStatus == 'RELEASED') {
     $scope.showSaveButton = false;
    } else {
     $scope.showSaveButton = true;
    }
   }
  };
   
 });
    


If you want to do the reverse, i.e. communicate from child to parent, you use the $scope.$emit.

$emit(name, args): Dispatches an event name upwards through the scope hierarchy notifying the registered ng.$rootScope.Scope#$on listeners.


Labels: ,

Sep 16, 2013

AngularJS big picture : Overview

This is for the AngularJS starters. You will see handy diagrams and third-party links to get started with Angular JS, which is getting so much attention.

Q. Can you give a big picture of AngularJS highlighting its key components?
A. A good diagram is worth 1000 words.



A good link to get an overview of AngularJS. Once you get a high level understanding, go to YouTube and search for excellent AngularJS video tutorials to get started.


Q. What is a scope in AngularJS?
A. scope is an object that refers to the application model. It is the glue between application controller and the view. Both the controllers and directives have reference to the scope, but not with each other. It is an execution context for expressions and arranged in hierarchical structure. Scopes can watch expressions and propagate events.

Q. Can you explain the concept of scope hierachy? How many scopes can an application have?
A. Each Angular application has exactly one root scope, but may have several child scopes. The application can have multiple scopes, because child controllers and some directives create new child scopes. When new scopes are created, they are added as children of their parent scope. This creates a hierarchical structure similar to the DOM where they're attached.

When Angular evaluates a bound variable like say {{firstName}}, it first looks at the scope associated with the given element for the firstName property. If no such property is found, it searches the parent scope and so on until the root scope is reached. In JavaScript this behaviour is known as prototypical inheritance, and child scopes prototypically inherit from their parents. The reverse is not true. I.e. the parent can't see it's children's bound properties.

AnagularJS Interview Questions and Answers



If you are just starting with angularjs

Q. What do you understand by the term two way data binding in AngularJS?
A. The AngularJS ref and Overview

Q. Why is AngularJS popular?
A. Why does AngularJS rock?

The above references should get you started and prepare for key interview questions on AngularJS. Stay tuned for more AngularJS blog posts. Ther are other MVW frameworks like Backbone. Ember, etc.

Labels:

Sep 12, 2013

Working with Angular JS and jQuery UI : resizable TextArea to overcome IE limitation

AngularJS is a popular MVW (Model View Whatever) framework. Recently had an opportunity to test drive Angular JS for GUI development retrieving data via RESTful web service calls. The JavaScript based GUI frameworks like Angular JS, Backbone, etc will becom more poular and replace JSF. So, it really pays off to lean AngularJS if you like developing GUIs. If you go to YouTube, you will find a number of good beginner's tutorials to get started.


Q. What is a directive in AngularJS?
A. Directives extends HTML. During DOM compilation directives are matched against the HTML and executed. This allows directives to register behaviour, or transform the DOM. ng-app, ng-controller, ng-model, etc are directives. The directives can be placed in element names, attributes, class names, as well as comments. Directives are defined with camel cased names such as ngApp and invoked by translating the camel case name into snake case with these special characters :, -, or _. For example ng-ap p as in <html ng-app>




Q. When do you need to create your own directives?  How will you go about creating a custom directive in AngularJS?
A. There are instances where you want to use jQuery UI plugins. Reecently, I had to use the the jQuery Resizable plugin with angular to resize my TextArea in IE 8 as it is the standard browser used by our business and operational staff. Here are some code samples to get AngularJS and jQuery to work together.  By default, the Angular JS is shipped with a lite version of jQuery, but not with the UI plugins.



Step 1: You need to define directives.  Directives are a way to teach HTML new tricks. During DOM compilation directives are matched against the HTML and executed. I am using RequireJS to manage dependencies. here is myTextAreaWithModel.js file


'use strict';

define([ 'jqueryui' ], function() {

 
 function myTextAreaWithModel() {
  return {
   require: 'ngModel',
   // Restrict it to be an attribute in this case
   restrict : 'A',
   // responsible for registering DOM listeners as well as updating the
   // DOM
   link : function($scope, $element, $attrs) {
    jQuery(function() {
     jQuery("textarea.resizableAreaWithModel").resizable();
    });
   }
  };
 }

 return myTextAreaWithModel;
});


Step 2:  A sample bootstrapping JS file that uses require js to manage dependencies. The key here is to see how jquery-ui is loaded. You can choose to ignore the rest.

'use strict';

/**
 * Configure JS file paths and dependencies
 */
var requireConf = {
    baseUrl: '.',   // This will be the path to portal.html
    shim: {
        'angular'             : { deps: ['jquery'] },
        'jqueryui'            : { deps: ['jquery']},
        'bootstrap'           : { deps: ['jquery'] },
        'portal/portalCtrl'   : { deps: ['angular'] }
    },
    paths: {
        jquery    : 'lib/jquery/jquery',
        jqueryui  : 'lib/jquery/jquery-ui',
        angular   : 'lib/angular/angular-module',
        bootstrap : 'lib/bootstrap/js/bootstrap',
        text      : 'lib/require/plugins/text'
    },
    waitSeconds: 0,                 // Disable the RequireJS timeout
    urlArgs: ((myapp.debug) ? '' : 'v=' + (((new Date()).getTime() + '').substr(2,8)))   // URL cache breaker changes every second - TODO: use a version number instead : '';
};

require.config(requireConf);

/**
 * Load JS resources for the portal (but not for apps), then bootstrap Angular.
 */
require([
    'jquery',
    'angular',
    'portal/portalCtrl',
 
], function (jq, angular, portalCtrl) {

    angular.element(document).ready(function() {

        // Load the root controller for the page
        angular.module('portalModule.controller', [])
            .controller('portalCtrl', portalCtrl);

        // Load all angular style resources
        angular.module('portalModule', [
            'portalModule.controller',
            'portalModule.directives',
            'portalModule.services',
            'portalModule.filter'
        ]);

        // Bootstrap angular, this needs to be after the html page and the various JS resources defined above have loaded.
        angular.bootstrap(document, ['portalModule']);
    });
});


Step 3: Bootstrapping the "myTextAreaWithModel" using require js framework.

'use strict';

define([
    'angular',
    'utils/directives/myTextAreaWithModel'
], function (angular, myTextAreaWithModel) {

    angular.module('portalModule.directives', [])
         .directive('myTextAreaWithModel', myTextAreaWithModel);
});


Step 4: Finally the HTML code.

    ....
 <td width="30%">
  <textarea class="resizableAreaWithModel comments" 
     name="comments" ng-model="myAppStatus.comment" 
     jp-text-area-with-model 
  />
  </td>
  ....


Directives in angularjs are very powerful.


Labels: ,