PU$]-[KAR's

… Every drop has ability to survive .


Leave a comment

Angular4 on top of Angular2

The journey of AngularJS to Angular:

In 2009 Hevery (developer at google) began working on a project called Google Feedback. But the code grown up to almost 17000+ lines. So he decided to come with some strong framework or end-to-end tool that allowed web designers to interact with both the frontend and the backend. And from here the journey of Angular began. In older versions of angular (i.e. Angular 1.x) are known as AngularJS. Angular got released with massive success and got popular within no time. But after the time when Angularjs got involved in heavy projects, the drawbacks are started appearing epically about the core features of Angular. Especially regarding one of the core features of AngularJS like $scope and digest cycle. Those features started creating problems and such challenges leads to the newer version of AngularJS (known as only ‘Angular’) Angular 2. Then other major release comes up As Angular 4 (latest version).

Why not Angular 3:

Of course, after seeing the version number Angular 4 the oblivious question comes to mind why not Angular3?
Angular is being developed in a ‘MonoRepo’. The advantage of MonoRepo is, you don’t have to deal with the versioning of the code dependencies. But along the side huge developments were going on in the router section, like route-preload. So, @angular/router was already having the version 3.x. So, to avoid further confusion by launching Angular 3 having router version 4. It was better to release with Angular 4

Angular 4 compared with Angular 2:

More over Angular 4 or simply Angular is the next logical version of Angular2 but it has nothing in common with Angular 1 also called AngularJS. Angular 4 is continuation of Angular2.

  • Performance Improvement:

    The major worked have been carried out in Angular4 is regarding the performance. IT has been observed that initial loading time of the angular2 App was quite noticeable.
    The most of Angular 2’s life, there has just been the JIT (just in time) compiler, the compiler that runs in the browser. When an Angular2 application is bootstrapped in the browser, the JIT compiler performs a lot of work to analyze the components in the application at runtime and generate code in memory. When the page is refreshed, all the work that has been done is thrown away, and the JIT compiler does the work all over again.
    After that Angular team come up with AOT (Ahead-of-Time compiler). And using few commands Angular2 was could use AOT compilation to improve the performance.
    While releasing the Angular4, this was one of the major change which has been integrated in Angular4. The view engine of Angular4 has been significantly improved. These AOT modifications decrease the size of the generated code for those parts by approximately 60 percent. The more complicated the templates are, the greater the savings.

  • Animations:

    Animations being pulled out of @angular/core to remove the extra code being imported into our production bundle. Though you can easily add animation by importing {BrowserAnimationsModule} from @angular/platform-browser/animations into NgModule.

  • Email validation:

    In Angular2 we must apply RegEx. But now just put email as an attribute to input field where you want to have email id.

  • Typescript compatibility:

    In Angular 4 we can use typescript 2.1 or more earlier only up to typescript 1.8 was supported.

  • Debugging with Source Maps:

    In Angular4 if an error caused by something in one of the templates, they create source maps that provide a meaningful context concerning the original template.

  • Angular Universal:

    This release now contains the result of the external & internal work from the Universal team throughout the last few months. Most of this Universal code is currently located in @angular/platform-server.

  • Migrating to Angular4 from Angular2:

    Updating to Angular4 from Angular2 is easy. It’s as simple updating your Angular dependencies to the latest version, and double checking if you want animations.

Finally,

I would say, Angular will be a bit confusing for those who are from migrating from AngularJS 1.x. Due to significant changes between Angular and AngularJS. But for experienced developers who have more exposure to server-side coding standards along with some UI experience, then it will be very easy for them to use Angular and they will find it very helpful. I am saying this just because of the power given by the integration of typescript to the Angular. It empowers developer from server-side to use same standards and coding style while developing the UI applications. 😊
Yes, one should go ahead with Angular 4 instead of version 2.0. There is lot of update on existing feature and bug fixes in version 4 compared to version 2.0. As well as whatever the dependencies are going to be used in the application will be compatible with version 4.x. So, it is better to go with version 4.x and up.

Advertisements


Leave a comment

ng-if OR ng-show … ?

Good morning!!!

We always hear about prefer ‘ng-if’ than ‘ng-show’ but why??? What is the reason behind it? Then where we need to use ng-show and not ng-if? So today, I will be explaining these things in brief.

How they work …

First we will understand how ‘ng-if’ and ‘ng-show’ works.
In case of ng-if, control will gets rendered on to the page only when ‘if’ condition gets satisfied. Otherwise it will not get rendered on to the page.
Where as in case of ng-show all controls will get rendered on the page but only those controls are visible who have satisfied the condition for ng-show.

ng-if

In normal scenarios where we want to load controls conditionally, it is better to use ng-if because the controls which are required only those will get rendered on the page. This will even make page a bit lighter as well and performance will get improved too.
Even ng-if makes developer’s life easier especially validating the controls (like textboxes) using form validations (e.g. required field validation). The reason is in this scenario text box which are visible on the page will get validated because rest of the controls are not even rendered on the page. But if we use ng-show the controls which are hidden will also fire the validation because though they are not visible, they are already loaded on the page. So ng-show will complicate the scenario for validation.

ng-show

Now where we can use ng-show??? Consider a scenario where you want to maintain the state of controls (tough they are hidden because when ever you choose the same option again you want those controls back in the same state as they were in previous).

In this scenario we can use ng-show because all controls are already rendered on the page (just they may not visible). So these all controls will maintain there state always where as ng-if if will not allow controls to get rendered so controls will not be able to maintain there states. So in such scenario one can go for using ng-show instead of ng-if.

That’s all my friends!


Leave a comment

Jasmine unit test for ‘Directive’

Hey,

Today, we will go through unit tests for directive using ‘Jasmine’. We have to keep one thing in mind that Jasmine unit test is not ‘E2E’ testing framework. So we have to test our application module wise i.e. testing directives and services, controllers separately. To begin jasmine tests for directive we will consider a simple and very famous directive- ‘custom validation directive’.

Directive code:

var INTEGER_REGEXP = /^\-?\d*$/;
app.directive('integer', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (INTEGER_REGEXP.test(viewValue)) {
ctrl.$setValidity('integer', true);
return viewValue;
} else {
ctrl.$setValidity('integer', false);
return undefined;
}});}};});

This directive is simply responsible to check weather input is of type integer or not.

To test this directive we have to use a bit different technique that the previous. First we have to create a html on the fly which consumes this directive and then we have to assign the input value to this html. Once the value gets assigned, this custom validation will get fired.

The following code will describe the unit testing for this directive.

Unit test:

describe('directives', function() {
var $scope, form;
beforeEach(module('testDirective'));
beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope;
var element = angular.element("< form name="form">< input ng-model="model.integerInput" name="integerInput" integer />' +'</form>");
$scope.model = { integerInput: null }
$compile(element)($scope);
form = $scope.form;
}));
describe('integer', function() {
it('should pass with integer', function() {
form.integerInput.$setViewValue('3');
$scope.$digest();
expect($scope.model.integerInput).toEqual('3');
expect(form.integerInput.$valid).toBe(true);
});
it('should not pass with string', function() {
form.integerInput.$setViewValue('a');
$scope.$digest();
expect($scope.model.integerInput).toBeUndefined();
expect(form.integerInput.$valid).toBe(false);
}); });});

Explaination:

As discussed earlier, here is one important thing to note that while creating unit test we have created a html on the fly which consumes our directive. So to convert this html string to ‘DOM’ we used $comiple().
Keep it in mind that we have warped ‘input’ control inside ‘form’ element because angularJS does not fire the validation until and unless form gets dirty so it is recommended that we should wrap it inside ‘form’.
‘$setViewValue’ is used to set the value to input control. Please don’t use DOM manipulation to set value to the input control. The reason behind this is by setting this value using ‘DOM’ handling ‘form’ will never come to know that something has been changed on the ‘form’ so eventually form will not be considered as ‘dirty’ and validation will not get fired and test will get failed. So proper way to use ‘$setViewValue’.
Finally trigger the digest cycle to let the test know the run-time changes.

And now test is set ready to ‘Go Green’…


Leave a comment

Restangular Service with Jasmine unit test

Wel-Comeback

Unit testing AngularJS service with Restangular is one of the common coding issue and that too with testing inside the ‘promises’ as well. So today we will look at how to write and test a service inside ‘promise’ using Jasmine unit test framework. We will go with the example given below.

Specifically we are looking at a service which is returning a data from a .json file instead of hitting http url.

//defining a module with factory
angular.module('SampleTest').factory('TestFactory',TestFactory);
Function TestFactory(Restangular,ObjectRepositaory){
// creatinga samplefunction
return{sampleFunction:function(){
//setting URL for retangular to call API
var restangular = Restangular.withConfig(function (configurer){configurer.setBaseUrl('mockData/data'); configurer.setRequestSuffix('.json')});
return Restangular.all('dataFile').getList().then(function (response){
//inside promise
ObjectRepositaory = response;
}}}

Description:

So we have created ‘sampleFunction’ inside a factory named ‘TestFactory’. So basically in this function we are fetching a data resided in ‘dataFile.json’ and once the service returns ‘success’ we are storing this data in to an repository called ‘ObjectRepositaory’.

Now we  will test this function using a ‘Jasmine’ framework. So as discussed earlier to begin with unit test we will create ‘describe’ block as test suit which will have necessary injections in ‘beforeEach’ function and followed with ‘it’ the actual test case.

So have a look at a test case written below.
describe('Test', function(){ var httpBackend, Restangular;
beforeEach(function() {module('SampleTest');});
beforeEach(inject(function( _Restangular_, _$httpBackend_) {
httpBackend = _$httpBackend_;
Restangular = _Restangular_;
}));
describe('Test result', function(){
it('A description of what should the method do', inject(function(TestFactory,ObjectRepositaory){ spyOn(Restangular, 'all').andCallThrough();
// a mock to be returned from http
var dummyResponse = [{id:1,name:'ABC'}];
//This whenGET is used in case of json mocked service
httpBackend.whenGET(URL).respond(dummyResponse);
//This whenGET is used in case of actual http url
//httpBackend.expectGET(URL).respond(dummyResponse);
TestFactory.sampleFunction();
// important to flush the backend to unproxy the restangular promise
httpBackend.flush();
// expect the objectRepositary has a result
expect(ObjectRepositaory.length).toEqual(1);
}));
});
});

Explanation:

So, As you observed we have injected ‘Restangular’, ‘$httpBackend. Here we are using ‘httpBackend’ for mocking a service. We have mocked response as ‘dummyResponse’ which is eventually going to be returned by a fake service call.
In above code you will see the use of ‘httpBackend.whenGET’ instead of ‘httpBackend.expectGET’ because it actually a difference ‘Request Expectation’ vs ‘Backend Defination’. We are using a json file data instated of actually calling a ‘http’ url which acts as backend for our application which doesn’t assert if a particular request was made or not, it just returns a trained response if a request is made. Even remember that due to not this we can’t check a service has been called or not using ‘toHaveBeenCalled’ (in case of using whenGET).

If we had used http url instead of .json then we might have used httpBackend.expectGET. The following link will explain httpBackend in more details. Click here
The most important thing is to use httpBackend.flush as described in code section.Only after the execution of flush() control goes inside the ‘susses promise’ and that is what we were looking for. Now each and every line inside a code is available for the tests. 🙂
Final assertion is doing exactly the same. Based on the service implementation what ever the response is returned by a service has to be copied in the repository object. So as per our test is considered as we mocked response with single item so the length of ‘ObjectRepositaory’ equals to one.

And that’s all my friends…


Leave a comment

Jasmine unit test for ‘controllers’

Welcome back guys,

As we have seen integration of ‘Jasmine’ and ‘karma’ with webstorm.Today, we will continue with the writing a JS unit test for a controller using ‘Jasmine’ & ‘karma’.
We will have an example of a simple. This controller is just a responsible for addition of the two numbers.
app.controller('addCtrl', function($scope, $location) {
console.log('add operation');
$scope.add=function(num1,num2)
{
$scope.result=parseInt(num1)+parseInt(num2);}});

In short controller ‘addCtrl’ contains a function ‘add’ which is returning a result of addition on two numbers: num1 & num2.Now we are going to write a JS test for the function.
Before begin with this first we need to add those dependent files in ‘karam.conf.js’ file under the ‘files’ section. Remember we have configured this file while initiating karma with few wizard steps. For reference click here. So as you can see below I have added few files along with ‘addCtrlSpec.js’. This file is going to contain tests for this controller.
files: [
'app/lib/angular.js',
'app/lib/angular-mocks.js',
'app/Controllers/additionController.js',
'TestFiles/addCtrlSpec.js',
],

Now following code snippet shows the actual code fore writing a spec.
describe('Test Addition', function ()
{ beforeEach(module('myApp'));
describe('myAppAddCtrlTest', function ()
{ it('Check Addtion test', inject(function ($controller)
{ var scope = {},
ctrl = $controller('addCtrl', {$scope: scope});
scope.add(4,5);
expect(scope.result).toBe(9); })); });

Explanation:

In this spec ‘describe’ is representing a test suit which can have multiple tests inside it. Whereas ‘beforeEach’ is the block which gets executed before ‘inner describe’. We can have ‘beforeEach’ even inside ‘inner describe’ or even inside ‘it’ as well but scope of that will be limited to that particular section only. Basically ‘beforeEach’ is used for injecting few modules or dependencies, mocking the data,carrying out specific action or initiating few variables etc. ‘it’ represents actual test. ‘it’ may contains more than one ‘expect’ statements. These expect statements are to check the result like checking the values of variable or method has been called or not. There are lots of options are available for these ‘expect’ statements.
So while looking at the code you can sense that,

  1. ‘Test Addition’ is my main test suit.
  2. Inside ‘beforeEach’ I have injected ‘myApp’ which is my main module of my application which contains all the controllers of my application. This ‘beforeEach’ will get executed every ‘inner descibe’ say ‘myAppAddCtrlTest’.
  3. it: ‘check addition test’ is the actual test. You can see that inside this ‘it’ I have injected a controller ‘addCtrl’ (along with the scope) which needs to be tested. And finally I called ‘add’ method using ‘scope’ and passed 4 & 5 as a dummy data to check weather this method is returning correct value or not.

Now this test is ready to run. In ‘karma’ we can’t run the individual test so to run the tests we need to start ‘karma’ first & then need to run tests. So to run that we can go to file ‘karma.conf.js’ file in project structure and write click in that and say run and will see the ‘karma’ has been stared in default browser and test is running green.

So in further posts we will discuss with directives and services too.

Till then bye!!!


2 Comments

Integration of ‘Jasmine’ with ‘Webstorm’

Hey guys,

It’s time to have some hands-on with unit testing !!!

Unit testing is one of the key features while developing any application weather it would be a server side code or client side and ‘Jasmine’ is one of the leading framework to test an angularJS application.So today we will walk through integrating ‘Jasmine’ with ‘WebStorm’.Of course, we should have ‘node.js’ installed on our machine that’s the prerequisite thing for this as you know. So basically to run specs(i.e. jasmine tests) we are going to use ‘karma’ as ‘test runner’ & ‘jasmine’ as test framework.

So majorly this integration will fall in two steps:

  1. Initialization of ‘karma’.
  2. Adding ‘jasmine’ intellisense.

Initializing ‘karma ’ with ‘jasmine’ framework.

  • Install ‘karma’ inside webstorm project with command on terminal ‘npm install –g karma’ which installs the ‘karma’ for our application even we might go for installing karma globally using command prompt.
  • To initialize ‘karma’ enter command ‘karma init’ on terminal. This command will initialize the karma and will be followed with certain questions to configure ‘karma.conf.js’. basically this file will be set through the option which we are going to set while initializing ‘karma’.
  • So using this configuration option we can adopt different Test frameworks like ‘Jasmine’, ‘mocha’ etc. so we are going through ‘Jasmine’ configuration. As I said earlier ‘karma ’ is a test runner & ‘Jasmine’ is a test framework.
  • So to configure this we will chose ‘jasmine’ framework. Then ‘no’ to Rquire.js. Then chose the suitable browser say ‘firefox’ then As we want that ‘ webstorm’ has to look after change in any tests so select ‘no’ to the question ‘Do you want Karma to watch all the files and run the tests on change ?’

So this will set our basic configuration.

And now it’s time to add few things in favor of developer’s favor – Intellisense.

‘Jasmine’ framework intellisense:

As with default options ‘webstorm ’ is not going to provide any auto complete facility for jasmine so we do some settings to make it possible. For that we need to add java script library to have that through settings of webstorm and need to include in current project.

To that please follow following steps:

  • In WebStorm, open the Settings dialog (File > Settings).
  • Under language & settings, navigate to JavaScript > Libraries.
  • Click the Download button on the right side. This opens the Download Library dialog.
  • Select “TypeScript community stubs” from the combo box.
  • Find the library ‘jasmine’, select it and click Download and Install.
  • After installing it makes sure that check box should be selected.

And now we are ready to go on writing specs……..

In next post even I will be going to share one easy sample for creating specs.


4 Comments

Re selecting same date in datepicker … from boot strap.

Once again datepicker comes in to action …

Guys, one the key issues with ‘datepicker’ is re selecting the same date in bootstrap datepicker control. Let’s consider a scenario that user has already selected a date say 1st Aug. 2014 so of course that date will get highlighted and now by mistake is again selecting a same date, in that case date say 1st Aug. 2014 (which is already selected) will gets deselect. And of-course multi-date selecting is false. So this is very odd behavior of user some times (specially in case where selecting a same date is not a functionality to deselect it.)

You can see this issue on

click here

So to resolve this issue we need to understand how datepicker runs behind the seen i.e. ‘bootstrap-datepicker’ js file.

Below code is a snap shot from datepicker bootstrap.js file


_toggle_multidate: function(date){
var ix = this.dates.contains(date);
if (!date){
this.dates.clear();
}
else if (ix !== -1){
this.dates.remove(ix);
}
else {
this.dates.push(date);
}
if (typeof this.o.multidate === 'number')
while (this.dates.length > this.o.multidate)
this.dates.remove(0);},

Analysis of existing code:

As shown in above code variable ‘ix’ holds index number (from an array of selected dates i.e. ‘this.dates’) if it founds duplicate date and if ‘ix’ holds value other than -1 then it shows that the selected date is duplicate one i.e. it already has been selected. So it removes that date from an array ‘this.dates’ so it won’t be able to select i.e. highlight it on UI.
So this is the section that we need to look at.

Solution:

To avoid such problem we can create a property as ‘multidateRemoveDuplicate’ which will be deciding factor to select of deselect duplicate date because user come across scenarios such as
1. If user re select already selected date it should get deselect
2. The selected date gets deselect only in case when some different date is selected.
(of course multi date selection is blocked in both cases).

So if the value of ‘multidateRemoveDuplicate’ is set to true then it will removes already selected date and if it is false then it wont.

Modified code:

To create ‘multidateRemoveDuplicate’ property we need to add following code in bootstrap-datepicker.js file.

1. The following code will assign default value to ‘multidateRemoveDuplicate’ as false.

var defaults = $.fn.datepicker.defaults = {
autoclose: false,
beforeShowDay: $.noop,
calendarWeeks: false,
clearBtn: false,
daysOfWeekDisabled: [],
endDate: Infinity,
forceParse: true,
format: 'mm/dd/yyyy',
keyboardNavigation: true,
language: 'en',
minViewMode: 0,
multidate: false,
multidateRemoveDuplicate: false,
multidateSeparator: ',',
orientation: "auto",
rtl: false,
startDate: -Infinity,
startView: 0,
todayBtn: false,
todayHighlight: false,
weekStart: 0
};

2. The following code need to add along with other set properties which are already exist and it is to set a value to property ‘multidateRemoveDuplicate’ (setter method)

setMultidateRemoveDuplicate: function (multidateRemoveDuplicate) {
this._process_options({ multidateRemoveDuplicate: multidateRemoveDuplicate });
this.update();
this.updateNavArrows();
},

3. The following code is to  default call set property of ‘multidateRemoveDuplicate’ i.e. ‘setMultidateRemoveDuplicate’ with ther set properties which are already exist.

var Datepicker = function(element, options){
.
.
this.setStartDate(this._o.startDate);
this.setEndDate(this._o.endDate);
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
this.setMultidateRemoveDuplicate(this.o.multidateRemoveDuplicate);
this.fillDow();
this.fillMonths(); ...

Now we have to modify a code for _toggle_multidate function as given below.
The date will get removed from an array of dates based on the value assigned to ‘multidateRemoveDuplicate’

_toggle_multidate: function(date){
var ix = this.dates.contains(date);
if (!date){
this.dates.clear();
}
else if (ix !== -1){ if (this.o.multidateRemoveDuplicate) {
this.dates.remove(ix);} }
else {this.dates.push(date);}
if (typeof this.o.multidate === 'number')
while (this.dates.length > this.o.multidate)
this.dates.remove(0);},

And we can assign a value from our code based on the user requirement weather user re select already selected date it should get deselect or the selected date gets deselect only in case when some different date is selected.

That’s all my friends. Have a nice day!!! ….

🙂