tag:blogger.com,1999:blog-10076513497294941272024-03-05T00:39:16.666-08:00My online NotebookAnonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.comBlogger90125tag:blogger.com,1999:blog-1007651349729494127.post-62920158581915244582015-11-07T20:52:00.001-08:002015-11-07T20:52:25.954-08:00A Few Tips on Gulp<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
I have been using Gulp a lot these days and have encountered a few cases that are a bit tricky to solve if you are new to Gulp. These scenarios get even trickier if you used Grunt before and just started using Gulp later, like myself. This is because, Grunt is synchronous and the execution of a Grunt task that combines a set of tasks is predictable. On the other hand, Gulp is asynchronous and we need to carefully examine the way a combined task runs in order to get maximum benefits out of it.
<br />
<br />
The asynchronous behavior of Gulp tasks makes it a bit difficult to perform things like chaining multiple tasks, handling tasks not returning a stream work seamlessly and performing multiple operations in a single task. In this post, we will see how to handle these tasks.
<br />
<br />
<b><u>Chaining Multiple Tasks</u></b>
<br />
It is common to define multiple tasks and combining them to create a master task. The master task alone is called whenever there is a need to perform the set of tasks together. Some of these tasks may be dependent on each other and others may be independent. In general, a set of Gulp tasks are combined using the following syntax:
</span>
<br />
<pre class="brush: jscript">gulp.task('build', ['copy-files', 'concat-files', 'run-tests', 'copy-coverage-results']);
</pre>
<span class="spanText">
Out of these tasks, the task concat-files is dependent on the task copy-files. The above setup starts executing these tasks at the same time. Execution of the task concat-files is not paused until execution of the task copy-files is completed. It can be solved in two ways. One way is to declare the task copy-files as a dependent task on the task concat-files and have the concat-files task alone as dependency on the build task.
</span>
<br />
<br />
<pre class="brush: jscript">gulp.task('concat-files', ['copy-files'], function(){
//definition of the task
});
</pre>
<br />
<br />
<span class="spanText">
The second way is to run these tasks in sequence using the <a href="http://npmjs.com/package/run-sequence" target="_blank">run-sequence</a> package. It is shown below:
</span>
<br />
<br />
<pre class="brush: jscript">var runSequence = require('run-sequence');
gulp.task('copy-and-concat', function(){
return runSequence('copy-files','concat-files');
});
</pre>
<br />
<br />
<span class="spanText">
We have to use one of these ways to solve this case based on the scenario in hand.
<br />
<br />
<b><u>Task not returning a Stream</u></b>
<br />
Sometimes we have to deal with tasks that don’t return streams. Such tasks are difficult to chain, as gulp doesn’t understand about their completion. One of such tasks is <a href="http://npmjs.com/package/gulp-requirejs" target="_blank">gulp-requirejs</a>. We need to wrap execution of such tasks inside gulp pipes to make them return streams. Following snippet wraps the gulp-requirejs task inside a pipe:
</span>
<br />
<br />
<pre class="brush: jscript">gulp.src('undefined.js')
.pipe(requires(/*configuration of the task goes here*/))
.pipe(gulp.dest('path-of-destiation'));
</pre>
<br />
<br />
<b><u>Task handling Multiple Operations</u></b>
<br />
A task may handle multiple asynchronous operations. In such case, the task has to return a stream representing the combined execution. Sometimes, we can return the stream returned by the last operation alone, but this approach doesn’t guarantee that all tasks are completed by the time the stream is completed. So, it is a good practice to combine such tasks using the <a href="http://npmjs.com/package/event-stream" target="_blank">event-stream</a> package. Following snippet combines a number of copy operations into a single task using this package:
<br />
<br />
<pre class="brush: jscript">gulp.task('copy-files', function () {
return es.merge(
gulp.src('app/index.html')
.pipe(gulp.dest('build')),
gulp.src('app/JSON/*.json')
.pipe(gulp.dest('build/JSON')),
gulp.src('app/requirejs-config.js')
.pipe(gulp.dest('build/temp'))
);
});
</pre>
<br />
<br />
<span class="spanText">
I have encountered these cases quite a few times and the solutions discussed here worked well for me. These may not be the only possible ways to tackle these cases, but these are just my views. If you got any other ways to solve these problems, feel free to add a comment.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-43369951453408933762015-10-10T08:44:00.000-07:002015-10-10T08:44:07.967-07:00Book Review - AngularJS by Example<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
I have just finished reading the book <a href="https://www.packtpub.com/web-development/angularjs-example" target="_blank">AngularJS by Example</a> authored by <a href="https://twitter.com/cmyworld" target="_blank">Chandermani Arora</a>. I will share my views on this book in this post.
<br />
<br />
A typical technology book starts with concepts on the technology and it continues to explain the technology throughout the book with independent examples. This book takes a different approach and start building an application right from beginning of the book. It continues adding features to the same example while explaining different concepts of the framework and covering internal details wherever needed.
<br />
<br />
Presentation of the entire book can be summarized into following the bullet points:
</span><br />
<ul><span class="spanText">
<li>Starts with a brief discussion on problems with building large JavaScript applications. Explains need of patterns like MVC in the ecosystem</li>
<li>Doesn't build a regular "Hello World" sample, instead builds an interesting sample to cover basic constructs of the framework</li>
<li>Before building any step of the sample, the author spends time in explaining the problem, then tells which feature solves the problem and then explains the feature thoroughly before implementing the next step</li>
<li>Covers a number of tips through examples</li>
<li>Makes good use of the notes section to clarify some basics and lesser known facts</li>
<li>No concept is explained independently. Most of the necessary features of the framework are covered with right examples that are very close to real world problems</li>
<li>I particularly like the way some features like animations, ng-model, interceptors and testing are explained in the book</li>
<li>Last chapter focuses on a few common scenarios and provides advice containing best practices to solve these problems</li>
</span></ul>
<span class="spanText">
<br />
<br />
This book doesn't just helps someone in gaining knowledge on AngularJS, but also teaches the needs of the features. Once you finish reading the book by following along with it and build the sample, you will have a self-built reference application that you can refer in the future.
<br />
<br />
The content in this book is relevant to both beginners and experienced developers working on AngularJS. A thorough read of this book will help you in mastering essential parts of the framework. You will also be able to answer most of the common interview questions once you <a href="https://www.packtpub.com/web-development/angularjs-example" target="_blank">read this book</a> :).
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com3tag:blogger.com,1999:blog-1007651349729494127.post-36998227860072580192015-09-25T00:00:00.002-07:002015-09-25T00:01:03.178-07:00Writing Gulpfile using TypeScript<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Lately, I have been using <a target="_blank" href="http://gulpjs.com/">Gulp</a> a lot at my work and also in the demos of my articles. I also use <a href="http://www.typescriptlang.org" target="_blank">TypeScript</a> quite often these days while <a href="http://www.sitepoint.com/getting-started-with-angular-2-using-typescript/" target="_blank">playing with Angular 2</a>. While using Gulp to transpile TypeScript to JavaScript using Gulp, I got thought to use TypeScript itself to write the gulpfile as well. It might sound a bit weird as we use Gulp to transpile the files to JavaScript and the gulpfile itself has to be converted by someone into JavaScript before any other task runs. Thanks to npm scripts, we have a way to achieve this.
<br />
<br />
The scripts section of the package.json file can be used to register commands and these commands can be executed from command prompt of any OS using the “npm run” command. For instance, if we have the following configuration saved in scripts section of package.json file:
</span>
<br />
<pre class="brush: jscript">
"scripts": {
"setup" : "npm install && bower install"
}
</pre>
<br />
<span class="spanText">
We can run the command “npm run setup” from the command prompt. This command would install all Node.js dependencies and the bower dependencies. We can transpile the gulpfile using this section and then combine this command with a command to run a task. For this, we need to have TypeScript installed globally. This can be done using the following command:
<br />
<br />
> npm install –g typescript
<br />
<br />
To write the gulpfile using TypeScript and take advantage of the type checking system, we need to get the type definition files. Type definitions for the gulpfile are available on tsd. Following command gets the type definitions for the gulpfile:
<br />
<br />
> tsd install gulp --save
<br />
<br />
These files are saved inside typings folder of the project. To make our lives easier, the tsd command creates a type definition file that refers to all of the installed type definitions. This file is tsd.d.ts inside the typings folder.
<br /><br />
Now, we need to refer the tsd.d.ts file in the gulpfile.ts file and start writing Gulp tasks. Following snippet shows a task that concatenates all JavaScript files:
<br />
</span>
<br />
<pre class="brush: jscript">
/// <reference path="typings/tsd.d.ts" />
var gulp = require('gulp'),
concat = require('gulp-concat');
gulp.task('default', function(){
return gulp.src(["scripts/*.js"])
.pipe(concat("combined.js"))
.pipe(gulp.dest("dist"));
});
</pre>
<br />
<span class="spanText">
This example is a simple one. In more advanced scenarios, we can use types as well.
<br />
<br />
To run this gulp task, we need to define a command in the scripts section to transpile the file and then run the task. Following is the command:
</span>
<br />
<pre class="brush: jscript">
"scripts": {
"concat": "tsc gulpfile.ts && gulp"
}
</pre>
<br />
<span class="brush: jscript">
All is done. We can now run this command as follows:
<br /><br />
> npm run concat
<br /><br />
Happy coding!
</span>
</div>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-41725736704417460442015-06-30T14:42:00.003-07:002015-07-05T08:17:19.100-07:00Debugging and Profiling LINQ Queries using Devart LINQ Insight<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Language Integrated Query (LINQ) is one of the features that makes .NET developers happy. LINQ opened up the opportunities to uniformly query in-memory objects, data in relational DBs, OData Services and many other data sources. Writing LINQ queries is fun as they reduce the usage of loops in code and keep the code base simple.
<br /><br />
There are several ways to write LINQ queries to obtain a given result. As programmers, it is our responsibility to find the best way out of them and use that to make the applications perform better. Also, LINQ queries are hard to debug. It is not possible to debug a LINQ query using immediate window of Visual Studio debugging tools. So, we can’t say if a LINQ query is completely correct unless we write enough unit tests around it. Though unit tests are a good way to verify, nothing beats the ability of debugging the query by changing parameters.
<br /><br /><a href="https://www.devart.com/linqinsight/" target="_blank">LINQ Insight</a> is a Visual Studio extension from <a href="https://www.devart.com/" target="_blank">Devart</a> that makes debugging and profiling LINQ queries easier. It also provides profiling data for the LINQ queries and for CRUD operations performed using LINQ to in-memory objects as well as LINQ to remote objects (LINQ to SQL, Entity Framework, NHibernate and others). In this post, we will see a few of the features of this tool.
<br /><br />
<b><u>Debugging LINQ Queries</u></b>
<br />
Once you installed LINQ Insight and restarted Visual Studio, you will see the options to see LINQ Interactive and LINQ Profiler windows under the View menu:
<br /><br />
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<span class="spanText"></span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHEY4xSmRGCXCRP4yLdwYX6YWcGHWAP2uq7GFrpmja3mCEJbEbqJ0viHtZdhYw3JSM2ZEpz1DV8O3BcsrPQfUoPAtushyZbpuydcy3yIk27Ijh2SIW-ips6Y8Cozzw6uI9-8ZBLCcrAXo/s1600/View+Menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHEY4xSmRGCXCRP4yLdwYX6YWcGHWAP2uq7GFrpmja3mCEJbEbqJ0viHtZdhYw3JSM2ZEpz1DV8O3BcsrPQfUoPAtushyZbpuydcy3yIk27Ijh2SIW-ips6Y8Cozzw6uI9-8ZBLCcrAXo/s400/View+Menu.png" width="400" /></a></div>
<br />
<br />
<span class="spanText">
To debug the queries, we need to view the LINQ Interactive window. Select this option to view the window. Say, I have the following generic list of Persons in my application:
</span>
<br />
<pre class="brush: csharp">var people = new List<Person>() {
new Person(){Id=1, Name="Ravi", Occupation="Software Professional", City="Hyderabad", Gender='M'},
new Person(){Id=2, Name="Krishna", Occupation="Student", City="Bangalore", Gender='M'},
new Person(){Id=3, Name="Suchitra", Occupation="Self Employed", City="Delhi", Gender='F'},
new Person(){Id=4, Name="Kamesh", Occupation="Business", City="Kolkata", Gender='M'},
new Person(){Id=5, Name="Rani", Occupation="Govt Employee", City="Hyderabad", Gender='F'}
};
</pre>
<br />
<span class="spanText">
Let’s write a LINQ query to fetch all males or, females from this list using a character parameter. Following is the query:
</span>
<br />
<pre class="brush: csharp">var gender = 'M';
var males = people.Where(p => p.Gender == gender).Select(p => new { Name=p.Name, Occupation=p.Occupation });
</pre>
<br />
<span class="spanText">
Right click on the query and choose the option “Run LINQ Query”. You will see this query in the LINQ Interactive window and its corresponding results.
</span>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtUBwsWBsFOfHyRbIkT52uJpAPqC6SJLhOmx0WfhOr-XEKllKDBoVoQfszm23SgnP6cxAmGOF-wQh_5yvNWRxoa59o2Dp1M8PQKlGMOkBrm0nKV62qI2NGbSTr6nW2fIrdVQhYBKcVB14/s1600/LINQ+Insight+LINQ+Query.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtUBwsWBsFOfHyRbIkT52uJpAPqC6SJLhOmx0WfhOr-XEKllKDBoVoQfszm23SgnP6cxAmGOF-wQh_5yvNWRxoa59o2Dp1M8PQKlGMOkBrm0nKV62qI2NGbSTr6nW2fIrdVQhYBKcVB14/s1600/LINQ+Insight+LINQ+Query.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw6zag5gsdylQ6Spb4MJc_3SgN3Cuf42fFRZjXFYodBlxpzXbrqScp1U3qqkVZ0ZNT3UNAvgYETpkSJNZGX3uLlK5vzltP3-SGSnPWpQdFRhff5pNKHUVj8riGOTLTes4v5VdIvFq9Fkc/s1600/LINQ+Insight+Query+result.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw6zag5gsdylQ6Spb4MJc_3SgN3Cuf42fFRZjXFYodBlxpzXbrqScp1U3qqkVZ0ZNT3UNAvgYETpkSJNZGX3uLlK5vzltP3-SGSnPWpQdFRhff5pNKHUVj8riGOTLTes4v5VdIvFq9Fkc/s1600/LINQ+Insight+Query+result.png" /></a></div>
<br />
<br />
<span class="spanText">
As the query accepts a parameter, we can change value of the parameter and test behavior of the query. Hit the Edit Parameters button in the LINQ Interactive window and modify value of the parameters used in the query. On clicking OK, the query is executed and the result is refreshed.
<br /><br />
<b><u>Profiling Calls to Entity Framework</u></b>
<br />
As most of you know, ORMs like Entity Framework convert LINQ Queries and function calls into SQL Queries and statements. The same result can be obtained using different types of queries. It is our responsibility to measure the execution time of all possible approaches of writing a query and choose the best one out of them.
<br /><br />
For example, consider a database with two tables: Student and Marks.
</span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZqrA9TkuTPtxzH_XPXaq-Hz9x1iXtkKDKgTAyW8glu-9M7BVJkRRM-oC-23buLcxXSUjJQhPrDVvxpT7yLrwq9plTTrXG4__3Estk9bhXpUdJVPU-5HkKOxzYkJY1N0RMOjoJm3CzDlI/s1600/DB+Diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZqrA9TkuTPtxzH_XPXaq-Hz9x1iXtkKDKgTAyW8glu-9M7BVJkRRM-oC-23buLcxXSUjJQhPrDVvxpT7yLrwq9plTTrXG4__3Estk9bhXpUdJVPU-5HkKOxzYkJY1N0RMOjoJm3CzDlI/s1600/DB+Diagram.png" /></a></div>
<br />
<br />
<span class="spanText">
The need is to find details of a student and the marks obtained by the student. It can be achieved in two ways. The first way is to find sum of the marks using navigation property on the student object and the other is to query the Marks DbSet using group by clause:
</span>
<br />
<pre class="brush: csharp">var studMarks1 = context.Students.Where(s => s.StudentId == studentid)
.Select(s => new
{
Name = s.Name,
Id = s.StudentId,
City = s.City,
TotalMarks = s.Marks.Sum(m => m.MarksAwarded),
OutOf = s.Marks.Sum(m => m.MaxMarks)
});
var studMarks2 = context.Marks.Where(m => m.StudentId == studentid)
.GroupBy(sm => sm.StudentId)
.Select(marksGroup => new
{
Name = marksGroup.FirstOrDefault().Student.Name,
Id = marksGroup.FirstOrDefault().Student.StudentId,
City = marksGroup.FirstOrDefault().Student.City,
TotalMarks = marksGroup.Sum(m => m.MarksAwarded),
OutOf = marksGroup.Sum(m => m.MarksAwarded)
});
</pre>
<br />
<span class="spanText">
Let’s see how much time does each of the above query takes using LINQ Profiler. Go to View menu and choose option to see the LINQ Profiler window. Now debug the application. After both of the queries are executed, visit the profiler window. You will see the data collected by the profiler. Following screenshot shows an instance of profiler’s data after running the above queries:
</span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGvQgNVN0kr_JJloY3LV3zqxeoZjAZzzht5AyeaIIi3HnJvaTnf-GFURB3FyCVbcfGX3evbkxUZNl3nXiu3-8ngk_Pr22vdlkwcCltp2YHyBdKRRyp3P4bpZwapNsmjs6K6KlxIaw2hLw/s1600/Profiling+Data.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGvQgNVN0kr_JJloY3LV3zqxeoZjAZzzht5AyeaIIi3HnJvaTnf-GFURB3FyCVbcfGX3evbkxUZNl3nXiu3-8ngk_Pr22vdlkwcCltp2YHyBdKRRyp3P4bpZwapNsmjs6K6KlxIaw2hLw/s1600/Profiling+Data.png" /></a></div>
<br />
<span class="spanText">
You can observe how much time each of these queries takes in different instances and with different values of the parameters before concluding that one of them is better than the other one.
<br /><br />
As we saw, <a href="https://www.devart.com/linqinsight/" target="_blank">LINQ Insight</a> adds a value add to the .NET developers. <a href="https://www.devart.com/" target="_blank">Devart</a> has a number of other tools to help developers as well. Make sure to check them out and use them to make your development experience more enjoyable!
<br /><br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com1tag:blogger.com,1999:blog-1007651349729494127.post-86954524312500420732015-06-13T12:30:00.001-07:002015-06-13T12:30:41.633-07:00Everything You Need to Know to Unit Test AngularJS Code<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Unit testing is one of the crucial and necessary parts of software development. This phase improves the quality of product, assures accuracy in behavior and also reduces the cost involved in fixing the bugs. There are some <a href="http://sravi-kiran.blogspot.com/2014/03/BasicsBenefitsOfWritingUnitTests.html" target="_blank">good advantages for a developer writing unit tests</a> as well.
<br />
<br />
AngularJS is one of the most popular framework for building Single Page Applications. One of the key reasons behind its success is, testability. Every piece of code written in AngularJS is unit testable. The features like Dependency Injection make the code written on the framework easier to test.
<br />
<br />
In the past, I wrote a few posts on unit testing AngularJS controller using Jasmine and QUnit and I also covered a few tips. Over past two years, I worked a lot on AngularJS and thus I wrote a lot of code and tests. This process taught me a lot of tips on unit testing AngularJS code that I wanted to share with the community. As some of you might be aware that I am a <a href="http://sitepoint.com/author/rkiran/" target="_blank">regular author for SitePoint</a>, I have put together a series of four articles covering tips on mocking and testing almost every block in AngularJS. Following are the links to these articles:
<br />
<br />
</span><br />
<ol><span class="spanText">
<li><a href="http://www.sitepoint.com/mocking-dependencies-angularjs-tests/" target="_blank">Mocking Dependencies in AngularJS Tests</a></li>
<li><a href="http://www.sitepoint.com/unit-testing-angularjs-services-controllers-providers/" target="_blank">Unit Testing in AngularJS: Services, Controllers & Providers</a></li>
<li><a href="http://www.sitepoint.com/angular-testing-tips-testing-directives/" target="_blank">AngularJS Testing Tips: Testing Directives</a></li>
<li><a href="http://www.sitepoint.com/angularjs-testing-tips-bootstrap-blocks-routes-events-animations/" target="_blank">AngularJS Testing: Bootstrap Blocks, Routes, Events, and Animations</a></li>
</span></ol>
<span class="spanText">
<br />
<br />
The process of putting these articles together has not been easy for me and at the same time, I enjoyed a lot while writing them. Read them when you get time and feel free to drop any feedback to me.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com2tag:blogger.com,1999:blog-1007651349729494127.post-10688670003662878242015-04-26T12:13:00.001-07:002015-04-26T12:16:51.631-07:00Getting Started with Benchpress<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Lately, most of us are quite busy with writing great front-end centric applications to make the look and feeling of our apps jazzy. Despite of the jazziness, the application won’t give a great experience to the user unless it performs really well on the browser. Performance of any piece of code can be improved only if we know that there is some scope for the improvement. Benchpress is one of the tools available to measure performance of AngularJS applications. In this post, we will see how to install benchpress and get started with using the data it provides us.
<br />
<br /><a href="https://github.com/angular/angular/tree/master/modules/benchpress" target="_blank">Benchpress </a>is a performance measuring tool built on top of Protractor. It is built by the Angular team and is extensively used by them to measure performance of the framework. It is made available and can be used by anyone to measure performance of the Angular apps.
<br />
<br />
<u><b>Installing Benchpress</b></u></span></div>
<br />
Benchpress is an NPM package. So, it needs Node.js to be installed. As it uses protractor, you need to install protractor globally. Use the following command to install protractor:
<br />
<br />
npm install –g protractor
<br />
<br />
If you are installing it on a Windows machine, webdriver-manager may throw an error. To oversome this, you will have to update the webdriver-manager. Following command updates it:
<br />
<br />
webdriver-manager update
<br />
<br />
Restart the command prompt after this command completes execution.
<br />
Install protractor again after updating the webdriver-manager and it shouldn’t fail this time. You can find more details on installing protractor in its official documentation on GitHub.
<br />
Now that the system has protractor available as a global package, we can install benchpress. Benchpress also has to be installed globally. Following is the command:
<br />
<br />
npm install -g generator-benchpress
<br />
<br />
<b><u>Getting a Glimpse of Benchpress ng-tasty</u></b>
<br />
Now that we have all of the required setup, we can apply benchpress on a project. For this post, I will show the benchpress results using the yeoman scaffold of ng-tasty. I will explain the process of getting benchpress results on an existing piece of code in a future article.
As we need to install a yeoman scaffold, you must have yeoman installed. If you don’t already have, run the following command to install it:
<br />
<br />
npm install –g yo
<br />
<br />
Create a new folder at your desired location and install the following NPM packages locally:
<br />
<ul>
<li>http-server</li>
<li>benchpress</li>
</ul>
<br />
<br />
Benchpress needs these packages to start the Node.js HTTP server and run the scenarios tests. The final thing that we need to get is, the yeoman scaffold. Run the following command in the same folder where the above NPM packages are installed:
yo benchpress ng-tasty
<br />
<br />
This scaffold adds a folder called benchmarks and inside this folder and the folder has following content:
<br />
<ul>
<li>protractorBenchmarks.conf.js: It is the configuration file for benchpress. It contains the browser details, spec files to run, test framework to use, the task to be performed before launching benchpress and a config object for jasmine</li>
<li>index.html: This file is inside the ng-tasty folder and it is the page to be inspected on</li>
<li>benchmark.spec.js: This file is inside the ng-tasty folder. The spec file that uses Selenium web driver to perform operations on the page</li>
</ul>
Now, we have everything to run benchpress and see some results. Run the following command on the console and see the outcome:
<br />
<br />
protractor benchmarks\protractorBenchmarks.conf.js
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CHJT14YQupYb4EDO_tztTiFL39iBFbbW_pnGopzZDk7_YkBCpk7k4J1zeSFdF420sbb9b6lXTZn4j0TVhTjVkq3iZIzqYO4Br7NBOGIabMKEX7rsM3gRN1AoRzhbk0I2EHkFSMDuLwk/s1600/Report.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CHJT14YQupYb4EDO_tztTiFL39iBFbbW_pnGopzZDk7_YkBCpk7k4J1zeSFdF420sbb9b6lXTZn4j0TVhTjVkq3iZIzqYO4Br7NBOGIabMKEX7rsM3gRN1AoRzhbk0I2EHkFSMDuLwk/s400/Report.PNG" height="300" width="570" /></a></div>
This command starts Selenium Web Driver and loads the index.html on Chrome. It performs the set of operations configured and prints results on the console.
<br />
<br />
<br />
Happy coding!
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com3tag:blogger.com,1999:blog-1007651349729494127.post-21165395517629508772015-01-07T12:19:00.001-08:002015-04-24T12:01:02.846-07:00Private Members in ES6 Classes<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Classes in ECMAScript 6 are easy to write and use. Yet, they have certain limitations. One of them is, there is no direct way to create a private member inside the class.
<br /><br />
The classes don’t allow us to declare variables directly inside body of the class. All members defined/declared inside the class or attached to an instance using this keyword are directly available to the instance of the class.
<br /><br />
When I Googled it, I found a few posts on it and answers suggesting to use <i>Symbol</i>. I think, <a href="http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-objects" target="_blank">Symbol</a> was private sometime back but according to the current draft of ES6, properties created using Symbol values are not private anymore. Though value of <i>Symbol</i> can't be reproducible, one can read <i>Symbol</i> properties using <i>Object.getOwnPropertySymbols</i>.
<br /><br />
For example, consider the following class and object:
</span>
<br /><br />
<pre class="brush: jscript">
const ID = Symbol();
class Employee{
constructor(id, name){
this.name = name;
this[ID] = id;
}
}
var emp = new Employee(1001, "Ravi");
</pre>
<br /><br />
<span class="spanText">
Though value of id is not accessible using <i>emp[Symbol()]</i>, as it returns a different <i>Symbol</i>, we can extract all <i>Symbol</i>s used for properties and values of these properties as:
</span>
<br /><br />
<pre class="brush: jscript">
var symbolsInEmp = Object.getOwnPropertySymbols(emp);
symbolsInEmp.forEach(function(symbol){
console.log(emp[symbol]);
});
</pre>
<br />
<br />
<span class="spanText">
The above snippet will print value of id stored in the object emp. If there are multiple <i>Symbol</i> properties, you may not be able to find which value corresponds to what value, but the data is not private.
<br /><br />
To make a value private, we can do one of the following:
<br /><br />
<ul>
<li>set and use the value inside a closure</li>
<li>create the variable inside a module and not export it</li>
</ul>
<br /><br />
<i>WeakMap</i> seems to be a good option for creating the private fields. Because, it accepts any value as key and it doesn’t prevent the key object from getting garbage collected when the <i>WeakMap</i> object still exists. It removes entry containing the object once it is garbage collected. For each private field, we need to create a new <i>WeakMap</i> object.
<br /><br />
Following snippet shows how <i>WeakMaps</i> can be used as private fields:
</span>
<br /><br />
<pre class="brush: jscript">
const ID = new WeakMap();
const PAN = new WeakMap();
class Employee{
constructor(id, name, pan){
this.name = name;
ID.set(this, id);
PAN.set(this, pan);
}
getPan(){
return PAN.get(this);
}
}
var emp = new Employee(1001, "Ravi", "FFHH1919JJ");
console.log(emp.getPan());
export default Employee;
</pre>
<br /><br />
<span class="spanText">
As you see, we are exporting the <i>Employee</i> class alone from the module. Here, the classes don't contain the fields themselves, but they are relying on the private objects of the module to keep the data private.
<br /><br />
Happy Coding!
</span>
</div>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com4tag:blogger.com,1999:blog-1007651349729494127.post-30600258335023063112015-01-01T10:26:00.001-08:002015-01-01T10:28:59.536-08:00Static Class Members in ES6<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
I have been playing with ECMAScript 6 for some time now and I must say that the new features added in this edition are worth taking a look. One of the significant language feature added in this specification is, support for classes. If you are not aware of the features of ES6, checkout the specification on <a href="http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts" target="_blank">official site for ECMA Script</a> or, the un-official HTML version of the specification on <a href="http://people.mozilla.org/~jorendorff/es6-draft.html" target="_blank">Mozilla’s site</a>.<br />
<br />
ES6 classes support most of the features like creating object, constructor, inheritance and overriding that are supported by Object Oriented programming languages like C# or Java. And because it is JavaScript, there is no static type checking.
<br />
<br />
I found it interesting when I saw the support for static members in the specification. The specification says, we can add a static method to a class using the following syntax:
</span>
<br />
<br />
<pre class="brush: jscript">static methodName(){
}
</pre>
<br />
<br />
<span class="spanText">
But, if you attempt to declare a static property as follows:
</span>
<br />
<br />
<pre class="brush: jscript">static propertyName;
</pre>
<br />
<br />
<span class="spanText">
It results in an error. So, we can’t declare a static property. But, we can create it inside a method and use it. To access a static member inside a static method, we need to use <i>this </i>keyword. Because, <i>this </i>reference in JavaScript refers to the object using which the method is invoked. Static methods are called using name of the class to which they belong and name of the class in JavaScript refers an object that has a prototype property containing instance members of the class. For example, consider the following class:
</span>
<br />
<br />
<pre class="brush: jscript">class Employee
{
constructor(){
this.name = "Ravi";
}
setName(name){
this.name = name;
}
}
</pre>
<br />
<br />
<span class="spanText">
The above code is similar to:
</span>
<br />
<br />
<pre class="brush: jscript">function Employee(){
this.name="Ravi";
}
Employee.prototype = {
setName: function(name){
this.name=name;
}
};
</pre>
<br />
<br />
<span class="spanText">
Here <i>Employee</i> is name of the class and at the same time, it is also an object. All static members of the <i>Employee</i> class are attached to the Employee object.
<br />
<br />
Let’s add a static method to the <i>Employee</i> class:
</span>
<br />
<br />
<pre class="brush: jscript">class Employee
{
constructor(){
this.name = "Ravi";
}
setName(name){
this.name = name;
}
static getCounter(){
if(!this.counter && this.counter!==0){
this.counter=0;
}
else{
this.counter++;
}
return this.counter;
}
}
</pre>
<br />
<br />
<span class="spanText">
The property counter used in the <i>getCounter</i> method of the above snippet becomes a static property, as it is assigned to this reference inside a static method. Similarly, another static method of the class can be called from a static method using this reference.
<br />
<br />
The following console.log statements will print the results specified in the comments:
</span>
<br />
<br />
<pre class="brush: jscript">console.log(Employee.getCounter()); //0
console.log(Employee.counter); //0
console.log(Employee.getCounter()); //1
console.log(Employee.counter); //1
console.log(Employee.getCounter()); //2
console.log(Employee.counter); //2
</pre>
<br />
<br />
<span class="spanText">
Happy Coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com2tag:blogger.com,1999:blog-1007651349729494127.post-88728963058496518102014-12-25T11:21:00.004-08:002014-12-25T11:22:44.663-08:00Automating Tasks in Front-end Web Apps Using Gulp<div dir="ltr" style="text-align: left;" trbidi="on">
As we started writing a lot of JavaScript and CSS these days, front-end development has matured like anything. We create hundreds of JavaScript source files to make our code organized; but finally we need to ship just one JavaScript file and one CSS file while deploying the application. This conversion is not easy; as it involves several steps like running tests, validating against jshint, concatenating, minifying, uglifying and many other tasks. Thankfully, we have a number of automated task runners and a handful of plugins on each of these task runners to make these tasks easier.
<br />
<br />
Out of the existing task runners, <a href="http://gruntjs.com/" target="_blank">Grunt</a> and <a href="http://gulpjs.com/" target="_blank">Gulp</a> are most widely used. I use Grunt a lot these days. Though I haven’t blogged about it, I used it in some of <a href="http://www.sitepoint.com/author/rkiran/" target="_blank">my SitePoint articles</a>. Lately, Gulp is becoming more famous. Gulp uses a different approach to address the same problem that Grunt addresses. Let’s see how we can leverage Gulp to automate our tasks.
<br />
<br />
Gulp is a task runner based on Node.js. It uses streams to carry its tasks. The way Gulp works is, it accepts a source (can be a file, or a set of files), processes them based on a task and passes it to the next task in the pipe for further processing. The pipes continues processing till the last task. Following is the syntax of a typical Gulp task:
<br />
<br />
<pre class="brush: jscript">gulp.task('task-name', function () {
return gulp.src([source paths])
.pipe(task1(parameters))
.pipe(task2())
...
...
...
.pipe(taskn())
.pipe(gulp.dest('destination-path'));
});
</pre>
<br />
<span class="spanText">
Tasks piped in the above Gulp task are tasks loaded using Gulp plugins. Gulp has a huge number of plugins contributed and actively developed by community, which makes it a very good ecosystem.
To be able to use Gulp in your project, you need to have it installed globally and locally. Run the following commands in a command prompt to get Gulp installed:
<br />
</span><br />
<ul><span class="spanText">
<li>npm installed –g gulp</li>
<li>npm installed gulp --save-dev (To be ran in your project folder)</li>
</span></ul>
<span class="spanText">
<br />
<br />
Let’s write a Gulp task for cleaning distribution files and regenerating them after concatenating and minifying. For this, we need the following Gulp plugins:
<br />
</span><br />
<ul><span class="spanText">
<li>gulp-clean</li>
<li>gulp-concat</li>
<li>gulp-uglify</li>
</span></ul>
<span class="spanText">
<br />
<br />
These can be installed using the following nom commands:
<br />
<ul>
<li>npm install gulp-clean --save-dev</li>
<li>npm install gulp-concat --save-dev</li>
<li>npm install gulp-uglify --save-dev</li>
</ul>
<br />
<br />
Add a file to the project and rename it to Gulpfile.js. Load the Gulp tasks in this file:
</span>
<br />
<br />
<pre class="brush: jscript">var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
clean = require('gulp-clean');
</pre>
<br />
<br />
<span class="spanText">
Before generating the files to be deployed, let’s clean the folder. Following task does this:
</span>
<br />
<br />
<pre class="brush: jscript">gulp.task('clean', function () {
return gulp.src(['dist'])
.pipe(clean());
});
</pre>
<br />
<br />
<span class="spanText">
Now, let’s create a bundle task that concatenates all JS files, uglifies them and copies inside a folder to be distributed. Following is the task:
</span>
<br />
<br />
<pre class="brush: jscript">gulp.task('bundle', function () {
return gulp.src(['public/src/*.js'])
.pipe(concat('dist/combined.js'))
.pipe(uglify())
.pipe(gulp.dest('.'));
});
</pre>
<br />
<br />
<span class="spanText">
The folder public/src contains all JS files of the application. They are concatenated into one file and the contents are then uglified and finally we call the dest task to copy the resultant file to destination, which is the dist folder.
<br /><br />
These two tasks can be combined into one task as follows:
</span>
<br />
<br />
<pre class="brush: jscript">gulp.task('createDist', ['clean', 'bundle']);
</pre>
<br />
<br />
<span class="spanText">
Now, if you run the following command, you will have the combined.js file created inside dist folder.
<br /><br />
gulp createDist
<br /><br />
To make a task default, name of the task has to be default.
<br /><br />
</span>
<br />
<pre class="brush: jscript">gulp.task('default', ['clean', 'bundle']);
</pre>
<span class="spanText">
<br /><br />
To run this task, you can run gulp command without passing names of any tasks to it.
<br /><br />
We will see explore more features of Gulp in future posts.
<br /><br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com2tag:blogger.com,1999:blog-1007651349729494127.post-45486322418579846522014-10-27T11:01:00.001-07:002014-10-27T11:33:26.642-07:00Form Validation and Displaying Error Messages using ngMessages in AngularJS 1.3<p><a href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md">AngularJS 1.3</a> was released around two weeks back. As the core Angular team says, it is the best AngularJS released till date. It comes with a bunch of new features and performance improvements.</p>
<p>One of the key changes in this release is the changes made to forms. The directives form and ngModel went through a number of changes to make it easier to perform validation. The framework has a new module, ngMessages that makes the job of displaying validation messages easier.</p>
<p>In the current release, FormController have following additional APIs:</p>
<ul>
<li><strong>$setUntouched()</strong>: A method that sets all controls in the form to untouched. It is good to call this method along with <em>$setPristine()</em></li>
<li><strong>$setSubmitted()</strong>: A method that sets the state of the form to submitted</li>
<li><strong>$submitted</strong>: A boolean property that indicates if the form is submitted</li>
</ul>
<p>NgModelController has the following additional APIs:</p>
<ul>
<li><strong>$setUntouched()</strong>: A method that sets the control to untouched state</li>
<li><strong>$setTouched()</strong>: A method that sets the control to touched state</li>
<li><strong>$validators</strong>: A list of synchronous validators that are executed when <em>$validate</em> method is called</li>
<li><strong>$asyncValidators</strong>: A list of asynchronous validators that are executed when <em>$validate</em> method is called</li>
<li><strong>$validate()</strong>: A method that executes all validators applied on the control. It calls all synchronous validators followed by asynchronous validators</li>
<li><strong>$touched</strong>: Boolean property that indicates if the control is touched. It is automatically set to true as soon as cursor moves into the control</li>
<li><strong>$untouched</strong>: Boolean property that indicates if the control is untouched</li>
</ul>
<p>For more details on these APIs, read the official API documentation of <a href="https://docs.angularjs.org/api/ng/type/form.FormController" target="_blank">FormController</a> and <a href="https://docs.angularjs.org/api/ng/type/ngModel.NgModelController" target="_blank">NgModelController</a>.</p>
<p>Let’s see these APIs and the new featured in action. Consider the following form:</p>
<br />
<pre class="brush: html"><form name='vm.inputForm' ng-submit='vm.saveNewItem()' novalidate>
Item Name: <input name='itemName' type="text" ng-model='vm.newItem.name' required non-existing-name />
<br />
Min Price: <input name='minPrice' type="text" ng-model='vm.newItem.minPrice' required ng-pattern='vm.numberPattern' />
<br />
Max Price: <input name='maxPrice' type="text" ng-model='vm.newItem.maxPrice' required ng-pattern='vm.numberPattern' greater-than='vm.newItem.minPrice' />
<br />
Quantity Arrived: <input name='quantity' type="text" ng-model='vm.newItem.quantity' ng-pattern='vm.numberPattern' />
<br />
<input type="submit" value="Save Item" />
</form>
</pre>
<br />
<p><em><strong>Note:</strong> Notice name of the form in the above snippet. It is not the way we usually name the HTML elements. We assigned a property of an object instead of a plain string name. Reason for using this is to make the form available in the controller instance. This approach is very useful in case of controllerAs syntax. (Credits: <a href="http://www.technofattie.com/2014/07/01/using-angular-forms-with-controller-as-syntax.html" target="_blank">Josh Caroll’s blog post</a>)</em></p>
<p>The form has some built-in validation and two custom validations. Built-in validations work the same way as they used to in the earlier versions (<a href="http://sravi-kiran.blogspot.com/2013/02/FormValidationUsingAngularJS.html" target="_blank"> Refer to my old blog post that talks a lot about the validations</a>). We will write the custom validations in a minute.</p>
<p>Following is the controller of the page. As stated above, I am using “controller as” syntax, so no <em>$scope</em> in the controller.</p>
<br />
<pre class="brush: jscript">var app = angular.module('formDemoApp', ['ngMessages']);
app.controller('SampleCtrl', function(){
var vm = this;
vm.inputForm = {};
vm.numberPattern = /^\d*$/;
vm.saveNewItem = function(){
vm.newItem={};
vm.inputForm.$setPristine();
vm.inputForm.$setUntouched();
};
});
</pre>
<br />
<p>
<u><strong>Custom Synchronous Validations</strong></u> <br />
<br />
The process of defining custom validations has been simplified in AngularJS 1.3 with <em>$validators</em> and <em>$asyncValidators</em>. We don’t need to deal anymore with <em>$setValidity()</em> to set validity of the control.</p>
<p>In case of synchronous validations, we need to return a boolean value from the validator function. The validation is passed when result of the validator function is true; otherwise, it fails.</p>
<p>In the form, we are accepting min price and max price values. The form should validate that the value of min price is always less than value of max price. Following is the directive for this validation:</p>
<br />
<pre class="brush: jscript">app.directive('greaterThan', function(){
return {
restrict:'A',
scope:{
greaterThanNumber:'=greaterThan'
},
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl){
ngModelCtrl.$validators.greaterThan= function(value){
return parseInt(value) >= parseInt(scope.greaterThanNumber);
};
scope.$watch('greaterThanNumber', function(){
ngModelCtrl.$validate();
});
}
};
});
</pre>
<br />
<p>If the above validation fails, it sets invalid flag to <em>greaterThan</em> validation on the control. Name of the method set to <em>$validators</em> is used as the validator string.</p>
<p><u> <strong>Custom Asynchronous Validations</strong> </u></p>
<p>In some scenarios, we may have to query a REST API to check for validity of data. As AJAX calls happen asynchronously, the validator function has to deal with promises to perform the task.</p>
<p>For the demo, I created a dummy asynchronous method inside a factory that checks for existence of the new item name in a static array and resolves a promise with a boolean value. Following is the service:</p>
<br />
<pre class="brush: jscript">app.factory('itemsDataSvc', ['$q',function($q){
var itemNames=['Soap', 'Shampoo', 'Perfume', 'Nail Cutter'];
var factory={};
factory.itemNameExists=function(name){
var nameExists = false;
itemNames.forEach(function(itemName){
if(itemName === name){
nameExists=true;
}
});
return $q.when(nameExists);
};
return factory;
}]);
</pre>
<br />
<p>The difference between synchronous and asynchronous validators is the API used to resister the validator and the return value of the validator method. As already stated, <em>$asyncValidators</em> of NgModelController is used to register the validator and the validator method has to return a promise. The validation passes when promise is resolved and the validation fails if the promise is rejected.</p>
<p>Following is the custom asynchronous validator that checks for unique name:</p>
<br />
<pre class="brush: jscript">app.directive('nonExistingName', ['itemsDataSvc','$q',function(itemsDataSvc, $q){
return {
restrict:'A',
require:'ngModel',
link: function(scope, elem, attrs, ngModelCtrl){
ngModelCtrl.$asyncValidators.nonExistingName = function(value){
var deferred = $q.defer();
itemsDataSvc.itemNameExists(value).then(function(result){
if(result){
deferred.reject();
}
else{
deferred.resolve();
}
});
return deferred.promise;
};
}
};
}]);
</pre>
<br />
<p><u> <strong>Validation Error Messages using ngMessages</strong> </u></p>
<p>Displaying validation messages of the form in AngularJS had not been too good earlier. It used to take a lot of mark-up and conditions to make them look user-friendly. AngularJS 1.3 has a new module, ngMessages that simplifies this task. If you refer to the module definition statement in the controller script, it has a dependency on ngMessages module. This module doesn’t come by default as part of the core framework, we have a separate file for this module.</p>
<p>The ngMessage module contains two directives that help in showing messages:</p>
<ul>
<li><strong>ngMessages</strong>: Shows or hides messages out of a list of messages</li>
<li><strong>ngMessage</strong>: Shows or hides a single message</li>
</ul>
<p>The directives in ngMessages module support animations as well. I will cover that in a future post.</p>
<p>In case of displaying form validation messages, <em>ngMessages</em> is set to the <em>$error</em> property of the form object and every occurrence of <em>ngMessage</em> element is set to the condition for which the message is has to be displayed.</p>
<br />
<pre class="brush: html"><div ng-if='vm.inputForm.$dirty &amp;&amp; vm.inputForm.$invalid' ng-messages='vm.inputForm.$error' class='error-messages'>
<div ng-message='required'>One/more mandatory fields are missing values</div>
<div ng-message='pattern'>Data is in incorrect format</div>
<div ng-message='greaterThan'>Invalid range</div>
<div ng-message='nonExistingName'>Name already exists</div>
</div>
</pre>
<br />
<p>By default, <em>ngMessages</em> displays the first message out of the list even if more than one message is relevant. It can b overridden using <em>multiple</em> or <em>ng-messages-multiple</em> attribute on the <em>ngMessages</em> directive.</p>
<p>The above message list is generic to the form; the messages are not specific to any of the control in the form. To display messages specific to form, you can use the <em>$error</em> property on the form element.</p>
<br />
<pre class="brush: html"><div ng-if='vm.inputForm.itemName.$dirty' ng-messages='vm.inputForm.itemName.$error' class='error-messages'>
<div ng-message='required'>One/more mandatory fields are missing values</div>
<div ng-message='nonExistingName'>Name already exists</div>
</div>
</pre>
<br />
<p>You can play with the sample on <a href="http://plnkr.co/edit/Gf9TgO096IXz0Mt13vcX" target="_blank">Plnkr</a>.</p>
<p>Happy coding!</p>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com2tag:blogger.com,1999:blog-1007651349729494127.post-89399583685812810062014-09-28T04:48:00.002-07:002014-09-28T04:49:52.456-07:00Unit Testing Config and Run Blocks in AngularJS<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
One of the best-selling points of AngularJS framework is testability. Any piece of code written in an AngularJS application is testable unless it is corrupted by a global object.
<br />
<br />
All of the blocks in AngularJS except config and run blocks can be instantiated or invoked and tested. Config and run blocks are executed as soon as the module containing the block is loaded into memory. There is no way to call them manually; unless the bodies of these blocks are defined independently and then hooked to a module. But, they are invoked automatically when the module is loaded. So, I don’t see a need to invoke them manually to test their logic.
<br />
<br />
Say, we have the following module with a config block registering routes and a run block that listens to a global message event to the window:
<br />
<br />
</span>
<br />
<br />
<pre class="brush: jscript">
var app = angular.module('testApp',['ngRoute']);
app.config(function($routeProvider){
$routeProvider.when('/', {templateUrl:'templates/home.html',controller:'homeCtrl'})
//definitions of other routes
.otherwise({redirectTo:'/'});
});
app.run(function($window, $rootScope){
$window.addEventListener('message', function(event){
$rootScope.$broadcast(event.data);
});
});
</pre>
<br />
<br />
<span class="spanText">
In test of the config block, we need to see if the methods when and otherwise are called with right parameters. To do that, we must spy these methods and store a reference of $routeProvider as soon as the module in loaded in tests. Providers cannot be mocked using $provide like services as they are not available after config phase. We can pass a callback to module loader and create spies on the methods whose calls have to be inspected.
<br />
<br />
Following snippet shows how to spy on a provider’s method and a test that checks if the method is called:
</span>
<br />
<br />
<pre class="brush: jscript">
describe('testing config block', function() {
var mockRouteProvider;
beforeEach(function () {
module('ngRoute', function ($routeProvider) {
mockRouteProvider = $routeProvider;
spyOn(mockRouteProvider, 'when').andCallThrough();
spyOn(mockRouteProvider, 'otherwise').andCallThrough();
});
module('testApp');
});
it('should have registered a route for \'/\'', function(){
expect(mockRouteProvider.when).toHaveBeenCalled();
});
});
</pre>
<br />
<br />
<span class="spanText">
If you run the above test now, it should fail. That’s strange, isn’t it?
<br />
<br />
I spent a lot of time struggling with it and found two approaches to make the above test pass.
<br />
<br />
One approach is to have a dummy test before the test that performs an assertion on the logic of config block. You can leave this test empty as it doesn’t have to do anything, or have an assertion that would always pass.
</span>
<br />
<br />
<pre class="brush: jscript">
it('doesn\'t have any assertions', function(){});
</pre>
<br />
<br />
<span class="spanText">
I didn’t like this approach; as it adds a test that would always pass and doesn’t carry any value. The other approach to make the above test pass is by calling inject() inside a beforeEach block. The inject function is generally used to get references of services that are needed in the tests. Even if there is no need of any service in the tests, the inject block can be called without any callback to bootstrap the modules already loaded using module() blocks.
<br />
<br />
</span>
<pre class="brush: jscript">
beforeEach(function(){
inject();
});
</pre>
<br />
<br />
<span class="spanText">
You will see the same issue with run() block as well. It isn’t executed unless a test is executed or inject block is executed.
<br />
<br />
If you got a better approach to bootstrap modules in tests, feel free to post a comment.
<br />
<br />
Happy coding!
</span>
</div>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-4688445220053098282014-09-06T11:33:00.001-07:002014-09-28T04:50:44.693-07:00Serializing and De-serializing JSON data Using ServiceStack<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
<a href="http://www.servicestack.net/">ServiceStack</a> is a light-weight, complete and independent <a href="http://www.github.com/ServiceStack">open source</a> web framework for .NET. I recently started playing with it and I must say that it is an awesome framework. It has several nice features including .NET’s fastest JSON serializer.
<br />
<br />
Each piece in ServiceStack can be used independently. So is its piece for serialization. The serialization package of ServiceStack can be installed via <a href="http://www.nuget.org/">NuGet</a> using the following command:
</span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghEBQBb8UYhAbgltjp5xuBaDzHeqcu0QAbZJIWuuEmaMSRgfEvh0dHeHDMAAOmDGbFDZQdsOevaFiTxQ_moKqrkFJDL-hTGO0XMTlNzXF2HAMzxfVR1B6KK96m54eEEdn2c0k1EMwZtto/s1600/ServiceStack-NuGet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghEBQBb8UYhAbgltjp5xuBaDzHeqcu0QAbZJIWuuEmaMSRgfEvh0dHeHDMAAOmDGbFDZQdsOevaFiTxQ_moKqrkFJDL-hTGO0XMTlNzXF2HAMzxfVR1B6KK96m54eEEdn2c0k1EMwZtto/s400/ServiceStack-NuGet.png" height="37" width="400" /></a></div>
<br />
<br />
<span class="spanText">
The above package can be installed on any type of application. Let’s use the following Person class for creating object to serialize/de-serialize:
</span>
<br />
<br />
<pre class="brush: csharp">public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Occupation { get; set; }
}
</pre>
<br />
<br />
<span class="spanText">
Following is a sample object of the person class:
</span>
<br />
<br />
<pre class="brush: csharp">var person = new Person()
{
Id = 1,
Name = "Ravi",
City = "Hyderabad",
Occupation = "Software Engineer"
};
</pre>
<br />
<br />
<span class="spanText">
To serialize this object to a JSON string, we need to use the <i>ServiceStack.Text.JsonSerializer</i> class. Following statement serializes the above object:
</span>
<br />
<br />
<pre class="brush: csharp">var serialized = JsonSerializer.SerializeToString(person);
</pre>
<br />
<br />
<span class="spanText">
The above string can be de-serialized using the following statement:
</span>
<br />
<br />
<pre class="brush: csharp">var converted = JsonSerializer.DeserializeFromString<Person>(serialized);
</pre>
<br />
<br />
<span class="spanText">
The <i>JsonSerializer</i> class also has APIs to serialize into or de-serialize from <i>TextWriter</i> or <i>Stream</i>.
<br />
<br />
The APIs in ServiceStack are light-weight and easy to use. I am working on a series of articles on this great framework. Stay tuned for updates.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-35535362427991099702014-06-27T23:44:00.001-07:002014-06-27T23:44:38.749-07:00Using Promises in NodeJS Apps<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
To separate logic of accessing data from the routes, we create separate modules to handle the task of data access. When I started learning Node.js, a common pattern that I saw in some samples to separate the data access logic from routing was as follows:
</span>
<br />
<br />
<pre class="brush: jscript">//Route
app.get(‘/api/students’, getAllStudents);
//In data access file
exports.getStudents = function(request, response){
mongoDbObj.students.find().toArray(function(err, data){
if(err){
console.log(err);
response.send(500,{error: err});
}
else{
console.log(data);
response.send(data);
}
});
};
</pre>
<br />
<br />
<span class="spanText">
Though this approach separates the logic, we are dealing with request and response inside the data access logic. I am personally not a fan of this approach. But, we cannot return the data or error from the above function as we will get them asynchronously. This is where I started thinking of using promises to refactor the above function.
<br />
<br />
We have several promise libraries available for Node.js. These days, I am playing with <a href="https://www.npmjs.org/package/bluebird" target="_blank">Bluebird</a>. It can be installed using npm.
<br />
<br />
One of the nice features that bluebird provides is, promisifying existing methods. To turn operations defined by an object into asynchronous, we need to pass the object inside the promisifyAll() method.
</span>
<br />
<br />
<pre class="brush: jscript">var Promise=require('bluebird');
var mongodb=Promise.promisifyAll(require('mongodb'));
</pre>
<br />
<br />
<span class="spanText">
The above snippet creates asynchronous versions of each of the function created inside the object mongodb. Let’s convert some of the snippets from my <a href="http://sravi-kiran.blogspot.com/2014/06/PerformingCrudOperationsOnMongodbInNodejsApplicationUsingMongodbDriver.html" target="_blank">previous post</a> to use async. Code for establishing a connection to MongoDB changes to:
</span>
<br />
<br />
<pre class="brush: jscript">
mongoClient.connectAsync('mongodb://localhost/studentsDb')
.then(function(db){
console.log("Connected to MongoDB");
mongoDbObj={
db:db,
students: db.collection('students')
};
}, function(error){
console.log(error);
});
</pre>
<br />
<br />
<span class="spanText">
Let’s fetch details of all students and return the results asynchronously to the caller. On the result of calling find() method, we need to call the asynchronous method toArray() to convert data from documents to array. It makes sense to return a promise in such scenario as we can’t say when the result will be available. Following is the snippet for fetching data that returns a promise:
</span>
<br />
<br />
<pre class="brush: jscript">
exports.getAllStudentsAsync=function(){
return new Promise(function(resolve, reject){
mongoDbObj.students.find()
.toArray(function(err, result){
if(err)
{
reject(err);
}
else{
resolve(result);
}
});
});
};
</pre>
<br />
<br />
<span class="spanText">
Finally, the REST API that sends the student data to the browser changes to:
</span>
<br />
<br />
<pre class="brush: jscript">
app.get('/api/students, function(request, response){
mongoOps.getAllStudentsAsync()
.then(function(data){
response.send(data);
}, function(err){
response.send(500,{error: err});
});
});
</pre>
<br />
<br />
<span class="spanText">
To me, this seems to be a cleaner approach as the request and response are sent to the model for manipulation. Feel free to express your opinions in the comments.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com1tag:blogger.com,1999:blog-1007651349729494127.post-86855909845851542092014-06-23T13:20:00.000-07:002014-06-23T13:22:54.639-07:00Performing CRUD Operations on MongoDB in Node.js Application Using mongodb Driver<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
A NoSQL database is the go-to choice while writing applications using Node.js. In particular, MongoDB has got a lot of popularity in the community. Thanks to the awesome MEAN (MongoDB-Express-Angular-Node) stack, that makes everyone realize that an entire web app can be written using just one language (JavaScript).
<br />
<br />
There are a number of drivers created by the community to interact with MongoDB from a Node.js app. The official mongodb driver seems to be the simplest of them. Because, the JavaScript API it provides to interact with MongoDB is quite similar to the way one talks to MongoDB from console. In this post, we will learn to perform simple CRUD operations on a MongoDB document store using the mongodb driver.
<br />
<br />
We will be dealing with a set of students that is initially loaded with the following data:
</span>
<br />
<br />
<pre class="brush: jscript">
{
"studentId" : 1,
"class" : 8,
"name" : "Ravi",
"marks" : [
{ "totalMarks" : 500, "percent" : 83.3 },
{ "totalMarks" : 510, "percent" : 85 } ],
},
{
"studentId" : 2,
"name" : "Rupa",
"class" : 8,
"marks" : [
{ "totalMarks" : 570, "percent" : 95 },
{ "totalMarks" : 576, "percent" : 96 } ]
}
</pre>
<br />
<br />
<span class="spanText">
To be able to work with the above data, we need to establish a connection with MongoDB first. Before that, we need to get the driver installed in the current project. Following command will install the driver when it is ran in the folder where the target Node.js project is located:
<br />
<br />
npm install mongodb
<br />
<br />
I prefer placing the code interacting with MongoDB in a separate file. As first thing, we need to get a reference to the MongoDB client and establish a connection:
</span>
<br />
<br />
<pre class="brush: jscript">
var mongoClient=require('mongodb').MongoClient;
var mongoDbObj;
mongoClient.connect('mongodb://localhost/studentDb', function(err, db){
if(err)
console.log(err);
else{
console.log("Connected to MongoDB");
mongoDbObj={db: db,
students: db.collection('students')
};
}
</pre>
<br />
<br />
<span class="spanText">
<b><u>Retrieving values:</u></b>
<br />
<br />
In the above connection URL, studentDb is name of the database. If the database doesn’t already exists, it is created automatically. I cached the students collection in the mongoDbObj object to avoid calling collections() over and over. Following statement fetches all students from the database:
<br />
<br />
</span>
<pre class="brush: jscript">
mongoDbObj.students.find().toArray(function(err, data){
if(err){
console.log(err);
else{
//operate with the deta
}
});
</pre>
<br />
<br />
<span class="spanText">
The find() method returns the objects in the form of documents. We need to convert the data obtained to a JavaScript array to operate with it easily. This is done by the toArray method.
<br />
<br />
Following are some examples showing using find with conditions:
<br />
<br />
</span>
<pre class="brush: jscript">
mongoDbObj.students.find({studentId:1}) //Fetches the student with value of studentId 1
mongoDbObj.students.find({studentId:{$gte:2}}) //Fetches the student with value of studentId greater than or equal to 2
mongoDbObj.students.find({"marks.totalMarks":500}) //Fetches the student with at least one of the values of totalMarks 500
mongoDbObj.students.find({"marks.totalMarks":{$lte:500}}) //Fetches the student with at least one of the values of totalMarks less than or equal to 500
</pre>
<br />
<br />
<span class="spanText">
<b><u>Inserting data:</u></b>
<br />
<br />
Inserting data is a straight forward operation. It needs the object to be inserted, an optional options object and a callback to handle the success or failure.
</span>
<br />
<br />
<pre class="brush: jscript">
mongoDbObj.students.insert(newStudent,{w:1},function(err, result){
if(err){
//Handle the failure case
}
else{
//Handle the success case
}
});
</pre>
<br />
<br />
<span class="spanText">
The value of options object passed in above call to insert method is used to get acknowledgement of write operations.
<br />
<br />
<u><b>Updating data:</b></u>
<br />
<br />
Following statement replaces the matched object:
<br />
<br />
</span>
<pre class="brush: jscript">
mongoDbObj.students.update({studentId:1},{name:”Ravi Kiran”},{w:1}, function(err, result){
//Handle success and failure
});
</pre>
<br />
<br />
<span class="spanText">
The issue with the above approach is, as it does a full replace, there is a possibility of losing data of other fields in the matched record. Following statement updates the specified fields leaving unspecified fields untouched:
</span>
<br />
<br />
<pre class="brush: jscript">
mongoDbObj.students.update({studentId:1},{$set: {name:”Ravi Kiran”}},{w:1}, function(err, result){
//Handle success and failure
});
</pre>
<br />
<br />
<span class="spanText">
<b><u>Deleting data:</u></b>
<br />
<br />
Calling remove() method without any conditions deletes all records in a collection:
</span>
<br />
<br />
<pre class="brush: jscript">
mongoDbObj.students.remove(function(err, result){
//Handle success and failure
});
</pre>
<br />
<br />
<span class="spanText">
If a condition is passed in, it deletes the records that match the criteria:
</span>
<br />
<br />
<pre class="brush: jscript">
mongoDbObj.students.remove({studentId:studentId},{w:1},function(err, result){
//Handle success and failure
});
</pre>
<span class="spanText">
We will discuss more about MongoDB and Node.js in future posts.
<br />
<br />
Happy Coding!
</span>
<br /></div>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com1tag:blogger.com,1999:blog-1007651349729494127.post-38874774523386918062014-06-08T11:00:00.000-07:002014-12-31T09:21:11.661-08:00Expanding my Writing Zone<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
I started this blog as a novice blogger less than 2 years back and I had an amazing writing experience till now. I just can’t say enough about the accolades I received from the readers of this blog and also some constructive criticism that helped me in writing better. Thanks to each one of you that are reading this blog. I will continue writing good content here. In addition to writing for my blog, I started writing content for two of leading content publishers on the internet.
<br />
<br />
<b><u>DotNet Curry Magazine:</u></b>
<br /><a href="http://www.dotnetcurry.com/magazine/" target="_blank">DotNet Curry Magazine</a> (DNC Magazine) is a free magazine for .NET developers around the world. It is started and ran by a set of technology experts including <a href="https://twitter.com/suprotimagarwal" target="_blank">Suprotim Agarwal</a>, a Microsoft MVP for ASP.NET/IIS. Suprotim is the Editor-in-chief for the magazine. The magazine releases an issue on every alternate month with high quality content on latest Microsoft Technologies. I am one of the thousands of subscribers to the magazine and I highly recommend subscribing to the magazine. The authors are MVPs and experts around the world. I am fortunate to have joined the team of authors. My first article for DNC was published during the May 2014 edition of the magazine and the article is now available on their website too, you can check it <a href="http://www.dotnetcurry.com/showarticle.aspx?ID=1016" target="_blank">here</a>. Stay tuned for lots of .NET content on <a href="http://www.dotnetcurry.com/magazine/" target="_blank">DNC Magazine</a> from all the authors.</span><br />
<span class="spanText"><br /></span>
<span class="spanText">Check my author page on DotNetCurry site: <a href="http://www.dotnetcurry.com/author.aspx?AuthorName=Ravi%20Kiran" target="_blank">http://www.dotnetcurry.com/author.aspx?AuthorName=Ravi%20Kiran</a><br />
<br />
<b><u>Site Point:</u></b>
<br /><a href="http://www.sitepoint.com/" target="_blank">Sitepoint</a> is a very well-known site for many developers as a source of knowledge on several topics including HTML, CSS, JavaScript, Mobile, UX, Design and other topics. They publish articles, books, courses and also have forums for Q&A. I read several of their articles focussed on front-end web technologies. I contacted Sitepoint to know I could write for them and the editor-in-chief <a href="https://twitter.com/OphelieLechat" target="_blank">Ophelie Lechat</a> accepted me as an author for their site. As most of you would have already guessed, I will be posting articles focused on JavaScript for Sitepoint. My first article for Sitepoint is published, you can read it <a href="http://www.sitepoint.com/implementing-authentication-angular-applications/" target="_blank">here</a>. Also check articles by other authors, they will help you for sure. I have a nice set of articles planned to be published for Sitepoint. Follow their <a href="https://twitter.com/sitepointdotcom" target="_blank">twitter feed</a> for tweets on their articles and also for technology news.
<br />
<br />Check my author page on SitePoint: <a href="http://www.sitepoint.com/author/rkiran/" target="_blank">http://www.sitepoint.com/author/rkiran/</a><br /><br />
I was busy in initiating my work for these writing assignments and writing articles. So, I couldn't get enough time to blog. But, I have a nice series planned for this blog and you will see the posts popping up soon.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-78531660204178148592014-05-08T15:05:00.000-07:002014-05-08T15:14:16.232-07:00Building a Todo list application using Node.js and Express.js on Visual Studio<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Some of you might have surprised to see the title containing Node, Express and Visual Studio together. Yes, it is possible to build Node.js applications on Visual Studio. In case, if you don’t know Visual Studio also has an extension for developing Python applications, you need to install the <a href="http://pytools.codeplex.com/" target="_blank">PTVS (Python Tools for Visual Studio)</a> to be able to do it. The team that developed on PTVS also developed <a href="http://nodejstools.codeplex.com/" target="_blank">NTVS (Node.js Tools for Visual Studio)</a> with help from a couple of community folks. NTVS is open source right from the beginning and accepts community contributions. The project is still in beta, so it has some pain points, but still it works pretty well. To follow along with this post, download and install the extension from its <a href="http://nodejstools.codeplex.com/" target="_blank">codeplex site</a>. It works with the 2012 and 2013 versions of Visual Studio.<br />
<br />
After installing NTVS, fire up Visual Studio and choose File -> New -> Project. In the dialog, expand Other Languages, and the node JavaScript under that. You will see a new option Node.js added here. Under this, you will find a number of project templates to start developing Node.js applications.
</span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU2CRNWlk4hpJUWkJy528xundTOEWzUobkQ1-TuQM5-g2p1fI4C3mQByS4bXMSCrFirPbTrBkz0-gtTH2ZKCqNc0NVScjjJOgneK1bOEkp1D4CH1_ubOQSA8jqm_1LLlxvHtihjakT2zk/s1600/Project+templates-sized.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU2CRNWlk4hpJUWkJy528xundTOEWzUobkQ1-TuQM5-g2p1fI4C3mQByS4bXMSCrFirPbTrBkz0-gtTH2ZKCqNc0NVScjjJOgneK1bOEkp1D4CH1_ubOQSA8jqm_1LLlxvHtihjakT2zk/s1600/Project+templates-sized.PNG" width="580" /></a>
<br />
<br />
<span class="spanText">
If you have <a href="http://www.typescriptlang.com/" target="_blank">TypeScript </a>installed, you will find the same set of templates under TypeScript node as well.
<br />
<br />
Let us start building a simple Todo list application using NTVS. From the new project dialog, select Blank Express Application, change name of the application to Express-Todo and hit OK.
<br />
<br />
The new project we just created has all the set up ready for developing a Node – Express application. The project has the following NPM packages installed; you can find them under the npm node in Solution Explorer.</span><br />
<span class="spanText"></span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCHDPulBCPN2-tKV1Zm2cQoi5lXgQkQU2thzbYeb6y2Jtpj97BjIYFn2XG6C0v2rqxvKwbLKWC1AJk_TGworKsswI5pw_3f4RLbvRtZeekF22QuMPAU45XkGZCUITsNIy60ilNF8ibzK8/s1600/NPM.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCHDPulBCPN2-tKV1Zm2cQoi5lXgQkQU2thzbYeb6y2Jtpj97BjIYFn2XG6C0v2rqxvKwbLKWC1AJk_TGworKsswI5pw_3f4RLbvRtZeekF22QuMPAU45XkGZCUITsNIy60ilNF8ibzK8/s1600/NPM.PNG" /></a>
<br />
<br />
<span class="spanText">
Express is a light weight server framework to develop Node.js applications. Jade is the most popular view engine used with express to compose the pages. Stylus defines a way to write CSS, takes many pain points of writing CSS away.
<br />
<br />
The app.js file generated with the project template has a number of middle-wares invoked for us to set up the node application.
</span>
<br />
<br />
<pre class="brush: jscript">app.set('port', process.env.PORT || 3000); //Port number configured for the application
app.set('views', path.join(__dirname, 'views')); //Folder under which the view files are stored
app.set('view engine', 'jade'); //Configuring view engine so that express parses them before rendering
app.use(express.favicon()); //Invoking favicon on startup
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public'))); //Stylus middleware invocation
app.use(express.static(path.join(__dirname, 'public'))); //Defining relative path for static files
</pre>
<br />
<br />
<span class="spanText">
Now run the application. You should be able to see a simple hello World kind of view in the browser.
<br />
<br />
We need another NPM package, underscore.js. It can be installed in two ways. One is using the dialog offered by NTVS or using npm command on the command prompt. Let us use the GUI dialog to install the package. Right click on the NPM node and choose “Manage npm Modules…”. Go to the tab “Search npm Repository” and type underscore. Choose the package highlighted in the screenshot and hit Install Locally. This step adds the package to the project and adds an entry of underscore to package.json as well.
</span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjthTi8SBZkHOt_N0raKsR1UB9cDSO9Hg1JikEaZORHiT0BW2nD0CyeTy3b-eipPcMCXX7TuHfoNWtoqo8-Axexac-aqk7SUtsROexB_ZsrcdNs8OwU58ekgIwQWhCSAeY0-76GfdQtQN8/s1600/underscore+.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjthTi8SBZkHOt_N0raKsR1UB9cDSO9Hg1JikEaZORHiT0BW2nD0CyeTy3b-eipPcMCXX7TuHfoNWtoqo8-Axexac-aqk7SUtsROexB_ZsrcdNs8OwU58ekgIwQWhCSAeY0-76GfdQtQN8/s1600/underscore+.PNG" /></a>
<br />
<br />
<span class="spanText">
Check the contents under npm node, you should be able to see the package underscore there.
<br />
<br />
Add a new JavaScript file to the folder routes and name it todos.js. This file will contain the API service to display and add todo items against an in-memory collection. Following is the code in the file:
</span>
<br />
<br />
<pre class="brush: jscript">var _ = require('underscore');
var listItems =
[
{
"id": 1,
"text": "Get Up"
},
{
"id": 2,
"text": "Brush teeth"
},
{
"id": 3,
"text": "Get Milk"
},
{
"id": 4,
"text": "Prepare coffee"
},
{
"id": 5,
"text": "Have a hot cup of coffee"
}
];
exports.list = function(req, res){
res.send(listItems);
};
exports.addToList = function (req, res) {
var maxId = _.max(listItems, function (item) { return item.id });
console.log(maxId);
var newTodoItem = { "id": maxId.id + 1, "text": req.body.text };
listItems.push(newTodoItem);
res.send({ success: true, item: newTodoItem });
};
</pre>
<br />
<br />
<span class="spanText">
I used underscore to calculate the next ID of the todo item. To use underscore, we need to add the require declaration at the beginning of the file, it is similar to the using statements in C# code files. All members to be exposed to the outside world have to be added to the exports object.
<br />
<br />
<span class="spanText">
In order to expose the above methods as APIs, we need to define the HTTP method and attach a route path to them. In the app.js file add the following statement at the top:
</span>
</span><br />
<pre class="brush: jscript">var todos = require('./routes/todos');
</pre>
<span class="spanText">
<br />
<br />
<span class="spanText">
This statement brings the module object exposed by the todos.js file. Now all we need to do is define routes, they are done as follows:
</span>
<br />
<br />
</span><br />
<pre class="brush: jscript">app.get('/api/todos', todos.list);
app.post('/api/todos', todos.addToList);
</pre>
<span class="spanText">
<br />
<br />
<span class="spanText">
That’s pretty easy, isn’t it? With this, we are done with the work on the server side. Let’s define the components on the client side. As first thing, let’s add jQuery to the layout page. You can install the package using bower and use it or you can point to a CDN as well. Let’s use Google’s CDN path to refer jQuery. Following is the jade tag that does this:
</span>
<br />
<br />
</span><br />
<pre class="brush: jscript">script(src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js")
</pre>
<br />
<br />
<span class="spanText">
Now, let’s update the index.jade file to contain the list items. Following is the mark-up of the modified index.jade file:
</span>
<br />
<br />
<pre class="brush: jscript">extends layout
block content
h1= title
p Welcome to #{title}
ul(id="todoList")
br
br
input(type="text" id="txtNewTodo")
button(id="btnAddTodo") Add New Todo
script(src="/javascripts/todoOperations.js")
</pre>
<br />
<br />
<span class="spanText">
As you see, in jade, one doesn’t require angle brackets to define the tags. It understands nesting through indentation. For indenting the tags, one can use either spaces or tabs; but not both.
We are yet to define the todoOperations.js file referred above. Let’s do it now. Add a JavaScript file to the javascripts folder under public folder and name it todoOperations.js. Code in this file is pretty straight forward, if you know jQuery.
</span>
<br />
<br />
<pre class="brush: jscript">var todoOperations = function () {
var todos;
function getAllTodos() {
//var deferred=$.defer();
return $.get("/api/todos", function (data) {
todos = data;
});
}
function addTodo(todoItem) {
return $.post('/api/todos', todoItem);
}
return {
getAllTodos: getAllTodos,
addTodo: addTodo
}
}();
var list;
function refreshTodos() {
todoOperations.getAllTodos().then(function (data) {
$.each(data, function () {
list.append("<li data-id='" + this.id + "'>" + this.text + "</li>");
});
});
}
$(function () {
list = $("#todoList");
$("#btnAddTodo").click(function () {
var textBox = $("#txtNewTodo");
if (textBox.val() !== "") {
todoOperations.addTodo({ "text": textBox.val() }).then(function (data) {
if (data.success === true) {
list.append("<li data-id='" + data.item.id + "'>" + data.item.text + "</li>");
textBox.val('');
}
});
}
});
refreshTodos();
});
</pre>
<br />
<br />
<span class="spanText">
Now run the application. You will be able to see the list of todo items populated on the page and you will also be able to add new todo items. </span><br />
<div>
<span class="spanText">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicPCcvcRgnvkaA6coppLukuQNwthS9OMBPgIN3L-waveDrri6ohyphenhyphenWdigRvybDDW_AY7ooeetzbgmgDG-I1D9y1ED1zZZvtGDR-bLxi9gpP1E5vrOa3jwFPfP55BqjyDNIMQrr3B_hk7c/s1600/Todo-Complete.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjicPCcvcRgnvkaA6coppLukuQNwthS9OMBPgIN3L-waveDrri6ohyphenhyphenWdigRvybDDW_AY7ooeetzbgmgDG-I1D9y1ED1zZZvtGDR-bLxi9gpP1E5vrOa3jwFPfP55BqjyDNIMQrr3B_hk7c/s1600/Todo-Complete.PNG" /></a> </span><br />
<div>
<span class="spanText"><span class="spanText">
To update and delete the todo items, you need to define the methods in the todos,js file and add routes for them in the app.js file using app.put and app.delete methods. I am leaving it as an exercise for you :)<br />
<br />
Happy coding!
</span>
</span></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-60680933098518004812014-04-17T13:20:00.000-07:002014-04-17T13:20:28.676-07:00$parsers and $formatters in Custom Validation Directives in Angular JS<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
While writing applications using Angular JS, sometimes we need to define our own validators. <a href="http://sravi-kiran.blogspot.in/2013/02/FormValidationUsingAngularJS.html" target="_blank">Custom validations</a> in Angular JS are created as directives with a dependency on the ng-model directive. At times, key part of the validation depends on controller of the ng-model directive.
<br />
<br />
The ng-model directive provides two arrays of functions to which the custom validation logic can be hooked: $parsers and $formatters. Usage of both of these arrays looks similar, but they are invoked under different conditions.
<br />
<br />
<b><u>$parsers:</u></b>
<br />
In most of the cases, $parsers is the right option to handle the logic of custom validation. Functions added to $parsers are called as soon as the value in the form input is modified by the user. As an example, consider the following directive:
</span>
<br />
<br />
<pre class="brush: jscript">app.directive('evenNumber', function(){
return{
require:'ngModel',
link: function(scope, elem, attrs, ctrl){
ctrl.$parsers.unshift(checkForEven);
function checkForEven(viewValue){
if (parseInt(viewValue)%2 === 0) {
ctrl.$setValidity('evenNumber',true);
}
else{
ctrl.$setValidity('evenNumber', false);
}
return viewValue;
}
}
};
});
</pre>
<br />
<br />
<span class="spanText">
This is a simple directive that checks if the number entered in the textbox is even. If we apply validation on a textbox, the validator works as long as the value is modified in the textbox.
<br />
<br />
<b><u>$formatters:</u></b>
<br />
Formatters are invoked when the model is modified in the code. They are not invoked if the value is modified in the textbox. $formatters are useful when there is a possibility of the value getting modified from the code. $formatters can be applied in the above directive using a simple statement:
<br />
<br />
</span>
<br />
<pre class="brush: jscript">ctrl.$formatters.unshift(checkForEven);
</pre>
<br />
<br />
<span class="spanText">
Now, the validation on the textbox containing the evenNumber is fired when the value is directly modified or even when the value is modified in the code.
<br />
<br />
A demo of the directive is available on <a href="http://plnkr.co/edit/Ld0ZfVvMLoQPm5lDHMbS?p=preview" target="_blank">plnkr</a>.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com1tag:blogger.com,1999:blog-1007651349729494127.post-61554735504486088712014-03-30T22:49:00.000-07:002014-03-30T22:49:07.178-07:00Basics: Benefits of Writing Unit Tests<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Quite often people ask the reasons of writing unit tests for their code. There are several benefits of writing unit tests that add value to the code as well as the developers writing the tests. I am listing a set of points here that came to my mind while thinking about the benefits of Unit testing.
<br />
<br />
<b><u>Benefits to code:</u></b>
<br />
<ul>
<li>The code will have very few bugs as most of them are identified and resolved while running tests</li>
<li>Silly mistakes are inevitable while writing code. Identifying them while running the application is difficult at times. Unit tests catch them instantly</li>
<li>Code doesn’t need documentation. Names of the behaviours or methods defined in unit tests shout the purpose of their part</li>
<li>Testable code is easily extensible too. Adding new features to the code becomes easy</li>
<li>If Unit tests are written right from beginning of development, the underlying code automatically follows a set of quality measures that are otherwise very difficult to achieve</li>
<li>After applying some modifications, the code can be shipped within very less amount of time, as most of the regression testing is also done by the unit tests</li>
</ul>
<br />
<br />
<b><u>Benefits to Programmers:</b></u>
<ul>
<li>Unit testing teaches good programing practices to developers</li>
<li>Unit tests force programmers to use some of the features of the language and framework that would otherwise remain just as theories in programmers’ minds</li>
<li>As we write more code, our thinking about code starts maturing. With unit tests, we are bound to write a lot of additional code than the usual production code. So, it improves the programmer’s ability to think logically</li>
<li>Programmers gain the experience of writing clean, loosely coupled code and learn the ways to avoid anti-patterns</li>
<li>It becomes very easy for any new member to understand and start working on the code</li>
</ul>
<br />
<br />
These are just my opinions. The list is definitely not limited to the above set of points. Feel free to put a comment on anything that I didn’t mention in the above list.
<br />
<br />
Happy coding!
</span>
<br /></div>Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-75581967949892175702014-03-09T13:59:00.001-07:002014-03-09T13:59:07.095-07:00A Closer Look at the Identity Client Implementation in SPA Template<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Sometime back, we took a <a href="http://sravi-kiran.blogspot.com/2013/11/ALookAtTheNewIdentitySystemInAspNet.html" target="_blank">look at the identity system in ASP.NET</a> and its support for both local and <a href="http://sravi-kiran.blogspot.com/2013/12/UsingExternalLoginProvidersWithAspNetIdentitySystem.html" target="_blank">remote accounts</a>. In this post, we will take a closer look at the way it is used in the Single Page Application template that comes with Visual Studio 2013.
<br />
<br />
The SPA application is a JavaScript client that uses an authenticated Web API. The Web API exposes a number of API methods to manage users. The JavaScript code uses jQuery for AJAX and Knockout for data binding has a number of methods that accomplish the task of managing the user. Let’s take a look at how the local users are authenticated.
<br />
<br />
<b><u>Identity Client Implementation for Local Users:</u></b>
<br />
If you check the Web API’s authentication configuration class, it exposes an endpoint at /Token for serving authorization token. Login credentials of the user have to be posted to this URL to get the user logged in. In response, the endpoint sends some data of which access token is a component. The access token has to be saved and used for subsequent requests to indicate the session of the logged in user.
<br />
<br />
Following code in the app.datamodel.js file sends a post request to the ‘/Token’ endpoint to login the user:
</span>
<br />
<br />
<pre class="brush: jscript">self.login = function (data) {
return $.ajax(loginUrl, {
type: "POST",
data: data
});
};
</pre>
<br />
<span class="spanText">
Following is the snippet from login.viewmodel.js that calls the above method:
</span>
<br />
<pre class="brush: jscript">dataModel.login({
grant_type: "password",
username: self.userName(),
password: self.password()
}).done(function (data) {
self.loggingIn(false);
if (data.userName && data.access_token) {
app.navigateToLoggedIn(data.userName, data.access_token, self.rememberMe());
} else {
self.errors.push("An unknown error occurred.");
}
});
</pre>
<br />
<br />
<span class="spanText">
There are a couple of things to be noticed in the above code:
<br />
</span><br />
<ul><span class="spanText">
<li>The property grant_type has to be set in the data passed to the login method</li>
<li>The navigateToLoggedIn method stores the access token in browser’s local storage to make it available for later use</li>
</span></ul>
<span class="spanText">
<br />
To sign up for a new user, we just need to post the user’s data to the endpoint at ”/api/Account/Register”. Once the user is successfully registered, it sends a login request to the token endpoint discussed above to login the user immediately. Code for this can be found in the register method of register.viewmodel.js file. Following is the snippet that deals with registering and logging in:
</span>
<br />
<br />
<pre class="brush: jscript">dataModel.register({
userName: self.userName(),
password: self.password(),
confirmPassword: self.confirmPassword()
}).done(function (data) {
dataModel.login({
grant_type: "password",
username: self.userName(),
password: self.password()
})
......
</pre>
<br />
<br />
<span class="spanText">
<b><u>Identity Client Implementation for External Login Users:</u></b>
<br />
Identity implementation for external accounts is a bit tricky; because it involves moving the scope to a public web site and a number of API calls. When the application loads, it gets the list of external login providers by sending an HTTP GET request to “/api/Account/ExternalLogins”. Following method in app.datamodel.js does this:
</span>
<br />
<br />
<pre class="brush: jscript">self.getExternalLogins = function (returnUrl, generateState) {
return $.ajax(externalLoginsUrl(returnUrl, generateState), {
cache: false,
headers: getSecurityHeaders()
});
};
</pre>
<br />
<span class="spanText">
The parameter returnUrl used in the above method is where the user would be redirected after logging in from the external site.
<br />
<br />
Based on the providers obtained from the server, the provider specific login buttons are shown on the page. When a user chooses to use an external login provider, the system redirects him to the login page of the chosen provider. Before redirecting, the script saves the state and the URL redirected in session storage and local storage (both are used to make it work on most of the browsers). This information will be used once the user comes back to the site after logging in. Following snippet in login.viewmodel.js does this:
</span>
<br />
<br />
<pre class="brush: jscript">self.login = function () {
sessionStorage["state"] = data.state;
sessionStorage["loginUrl"] = data.url;
// IE doesn't reliably persist sessionStorage when navigating to another URL. Move sessionStorage temporarily
// to localStorage to work around this problem.
app.archiveSessionStorageToLocalStorage();
window.location = data.url;
};
</pre>
<br />
<br />
<span class="spanText">
Once the user is successfully authenticated by the external provider, the external provider redirects the user to the return URL with an authorization token in the query string. This token is unique for every user and the provider. This token is used to check if the user has already been registered to the site. If not, he would be asked to do so. Take a look at the following snippet from the initialize method in app.viewmodel.js:
</span>
<br />
<pre class="brush: jscript">......
} else if (typeof (fragment.access_token) !== "undefined") {
cleanUpLocation();
dataModel.getUserInfo(fragment.access_token)
.done(function (data) {
if (typeof (data.userName) !== "undefined" && typeof (data.hasRegistered) !== "undefined"
&& typeof (data.loginProvider) !== "undefined") {
if (data.hasRegistered) {
self.navigateToLoggedIn(data.userName, fragment.access_token, false);
}
else if (typeof (sessionStorage["loginUrl"]) !== "undefined") {
loginUrl = sessionStorage["loginUrl"];
sessionStorage.removeItem("loginUrl");
self.navigateToRegisterExternal(data.userName, data.loginProvider, fragment.access_token, loginUrl, fragment.state);
}
else {
self.navigateToLogin();
}
} else {
self.navigateToLogin();
}
})
......
</pre>
<br />
<br />
<span class="spanText">
It does the following:
<br />
</span><br />
<ul><span class="spanText">
<li>Clears the access token from the URL</li>
<li>Queries the endpoint ‘/api/UserInfo’ with the access token for information about the user</li>
<li>If the user is found in the database, it navigates to the authorized content</li>
<li>Otherwise, navigates to the external user registration screen, where it asks for a local name</li>
</span></ul>
<span class="spanText">
<br />
The external register page accepts a name of user’s choice and posts it to ‘/api/RegisterExternal’. After saving the user data, the system redirects the user to login page with value of state set in the session and local storages and also sends the authorization token with the URL. The login page uses this authorization token to identify the user.
</span>
<br />
<br />
<pre class="brush: jscript">dataModel.registerExternal(self.externalAccessToken, {
userName: self.userName()
}).done(function (data) {
sessionStorage["state"] = self.state;
// IE doesn't reliably persist sessionStorage when navigating to another URL. Move sessionStorage
// temporarily to localStorage to work around this problem.
app.archiveSessionStorageToLocalStorage();
window.location = self.loginUrl;
})
</pre>
<br />
<br />
<span class="spanText">
For logout, an HTTP POST request is sent to ‘/api/Logout’. It revokes the claims identity that was associated with the user. The client code removes entry of the access token stored in the local storage.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-17082348410943261572014-02-17T10:31:00.000-08:002014-02-17T10:31:12.247-08:00Consuming ASP.NET Web API OData Batch Update From JavaScript<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
Consuming OData with plain JavaScript is a bit painful, as we would require handling some of the low-level conversions. <a href="http://datajs.codeplex.com/" target="_blank">datajs </a>is a JavaScript library that simplifies this task.
<br />
<br />
datajs converts data of any format that it receives from the server to an easily readable format. The batch request sent is a POST request to the path /odata/$batch, which is made available if batch update option is enabled in the OData route configuration.
<br />
<br />
As seen in the <a href="http://sravi-kiran.blogspot.in/2014/02/BatchUpdateSupportInAspNetWebApiOData.html" target="_blank">last post</a>, a batch update request bundles of a number of create put and patch requests. These operations have to be specified in an object literal. Following snippet demonstrates it with a create, an update and a patch request:
<br />
<br />
</span>
<br />
<pre class="brush: jscript">var requestData = {
__batchRequests: [{
__changeRequests: [
{
requestUri: "/odata/Customers(1)",
method: "PATCH",
data: {
Name: "S Ravi Kiran"
}
},
{
requestUri: "/odata/Customers(2)"
data: {
Name: "Alex Moore",
Department: "Marketing",
City:"Atlanta"
}
},
{
requestUri: "/odata/Customers",
method: "POST",
data: {
Name: "Henry",
Department: "IT",
City: "Las Vegas"
}
}
]
}]
};
</pre>
<br />
<span class="spanText">
Following snippet posts the above data to the /odata/$batch endpoint and then extracts the status of response of each request:
</span>
<br />
<br />
<pre class="brush: jscript">OData.request({
requestUri: "/odata/$batch",
method: "POST",
data: requestData,
headers: { "Accept": "application/atom+xml"}
}, function (data) {
for (var i = 0; i < data.__batchResponses.length; i++) {
var batchResponse = data.__batchResponses[i];
for (var j = 0; j < batchResponse.__changeResponses.length; j++) {
var changeResponse = batchResponse.__changeResponses[j];
}
}
alert(window.JSON.stringify(data));
}, function (error) {
alert(error.message);
}, OData.batchHandler);
</pre>
<br />
<br />
<span class="spanText">
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-50998580098891958312014-02-16T11:26:00.003-08:002014-02-16T11:26:51.444-08:00Batch Update Support in ASP.NET Web API OData<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
The <a href="http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api" target="_blank">ASP.NET Web API 2 OData</a> includes some new features including the support for batch update. This features allows us to send a single request to the OData endpoint with a bunch of changes made to the entities and ask the service to persist them in one go instead of sending individual request for each change made by the user. This reduces the number of round-trips between the client and the service.
<br />
<br />
To enable this option, we need to pass an additional parameter to the MapODataRoute method along with other <a href="http://sravi-kiran.blogspot.in/2013/08/PerformingCrudOperationsInWebApiODataServiceusingODataController.html" target="_blank">routing details we discussed in an older post</a>. Following statement shows this:
</span>
<br />
<br />
<pre class="brush: csharp">GlobalConfiguration.Configuration.Routes.MapODataRoute("ODataRoute", "odata", model,new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
</pre>
<br />
<br />
<span class="spanText">
I have a CustomerController that extends EntitySetController and exposes OData API to perform CRUD and patch operations on the entity Customer, which is stored in a SQL Server database and accessed using Entity Framework. Following is code of the controller:
</span>
<br />
<br />
<pre class="brush: csharp">public class CustomersController : EntitySetController<Customer, int>
{
CSContactEntities context;
public CustomersController()
{
context = new CSContactEntities();
}
[Queryable]
public override IQueryable<Customer> Get()
{
return context.Customers.AsQueryable();
}
protected override int GetKey(Customer entity)
{
return entity.Id;
}
protected override Customer GetEntityByKey(int key)
{
return context.Customers.FirstOrDefault(c => c.Id == key);
}
protected override Customer CreateEntity(Customer entity)
{
try
{
context.Customers.Add(entity);
context.SaveChanges();
}
catch (Exception)
{
throw new InvalidOperationException("Something went wrong");
}
return entity;
}
protected override Customer UpdateEntity(int key, Customer update)
{
try
{
update.Id = key;
context.Customers.Attach(update);
context.Entry(update).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
}
catch (Exception)
{
throw new InvalidOperationException("Something went wrong");
}
return update;
}
protected override Customer PatchEntity(int key, Delta<Customer> patch)
{
try
{
var customer = context.Customers.FirstOrDefault(c => c.Id == key);
if (customer == null)
throw new InvalidOperationException(string.Format("Customer with ID {0} doesn't exist", key));
patch.Patch(customer);
context.SaveChanges();
return customer;
}
catch (InvalidOperationException ex)
{
throw ex;
}
catch (Exception)
{
throw new Exception("Something went wrong");
}
}
public override void Delete(int key)
{
try
{
var customer = context.Customers.FirstOrDefault(c => c.Id == key);
if (customer == null)
throw new InvalidOperationException(string.Format("Customer with ID {0} doesn't exist", key));
context.Customers.Remove(customer);
context.SaveChanges();
}
catch (InvalidOperationException ex)
{
throw ex;
}
catch (Exception)
{
throw new Exception("Something went wrong");
}
}
}
</pre>
<br />
<br />
<span class="spanText">
Let’s use the batch update feature in a <a href="http://sravi-kiran.blogspot.in/2013/08/ConsumingWebApiODataFromNetAndJavaScriptClientApplications.html" target="_blank">.NET client application</a>. Let’s try adding a new customer and update an existing customer in the Customers table. Following code does this:
</span>
<br />
<br />
<pre class="brush: csharp">Container container = new Container(new Uri("http://localhost:<port-no>/odata"));
var firstCustomer = container.Customers.Where(c => c.Id == 1).First();
firstCustomer.Name = "Ravi Kiran";
container.UpdateObject(firstCustomer);
var newCustomer = new Customer() { Name="Harini", City="Hyderabad", Department="IT"};
container.AddToCustomers(newCustomer);
var resp = container.SaveChanges(SaveChangesOptions.Batch);
</pre>
<br />
<br />
<span class="spanText">
The last statement in the above snippet sends a batch request containing two requests: one to add a new customer and one to update an existing customer. The update operation calls the patch operation exposed by the OData API.
<br />
<br />
In next post, we will see how to perform batch update in a JavaScript client.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-57084565900059561062014-01-27T11:15:00.001-08:002014-01-27T11:15:36.102-08:00Creating a Todo List using Indexed DB and Angular JS<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="spanText">
In <a href="http://sravi-kiran.blogspot.com/2014/01/CreatingATodoListUsingIndexDbAndPromise.html" target="_blank">last post</a>, we saw how to use <a href="https://developer.mozilla.org/en-US/docs/IndexedDB" target="_blank">Indexed DB</a> with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise?redirectlocale=en-US&redirectslug=Web%2FAPI%2FPromise" target="_blank">promise API</a> implemented inside the browsers. In this post, we will rewrite the same sample using <a href="http://www.angularjs.org/" target="_blank">Angular JS</a>. So, instead of using promise API of the browser, we will use Angular’s <a href="http://docs.angularjs.org/api/ng.$q" target="_blank">$q</a>, as it makes the data binding system happy. And instead of performing the CRUD operations on Indexed DB inside a revealing module, we will do it inside a factory.
<br />
<br />
Indexed DB is available to the global scope. This means, it is a property of the window object. The best practice to use it in a factory is through the <a href="http://docs.angularjs.org/api/ng.$window" target="_blank">$window</a> object, as it is injectable and makes the factory testable. Following snippet shows first few statements of the factory:
</span>
<br />
<pre class="brush: jscript">var app = angular.module('indexDBSample', []);
app.factory('indexedDBDataSvc', function($window, $q){
var indexedDB = $window.indexedDB;
var db=null;
var lastIndex=0;
....
....
....
});
</pre>
<br />
<br />
<span class="spanText">
We need to add methods to open DB, get todo items, add new item and delete an item just as we did in the <a href="http://sravi-kiran.blogspot.com/2014/01/CreatingATodoListUsingIndexDbAndPromise.html" target="_blank">last post</a>. Logic in the methods remains the same, except usage of the promise.
<br />
<br />
The open method opens the database, checks for upgrade and handles the call back if it needs. It specifies the key property of the database while creating a new database.
</span>
<br />
<pre class="brush: jscript">var open = function(){
var deferred = $q.defer();
var version = 1;
var request = indexedDB.open("todoData", version);
request.onupgradeneeded = function(e) {
db = e.target.result;
e.target.transaction.onerror = indexedDB.onerror;
if(db.objectStoreNames.contains("todo")) {
db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "id"});
};
request.onsuccess = function(e) {
db = e.target.result;
deferred.resolve();
};
request.onerror = function(){
deferred.reject();
};
return deferred.promise;
};
</pre>
<br />
<br />
<span class="spanText">
The getTodos method fetches all available items in the DB and resolves promise with the results once all results are obtained. The fetch operation is performed using a cursor request, which returns the items individually from the indexed DB.
</span>
<br />
<br />
<pre class="brush: jscript">var getTodos = function(){
var deferred = $q.defer();
if(db === null){
deferred.reject("IndexDB is not opened yet!");
}
else{
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
var todos = [];
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
if(result === null || result === undefined)
{
deferred.resolve(todos);
}
else{
todos.push(result.value);
if(result.value.id > lastIndex){
lastIndex=result.value.id;
}
result.continue();
}
};
cursorRequest.onerror = function(e){
console.log(e.value);
deferred.reject("Something went wrong!!!");
};
}
return deferred.promise;
};
</pre>
<br />
<br />
<span class="spanText">
The addTodo method generated the next value for the key column and adds it to the Indexed DB.
</span>
<br />
<br />
<pre class="brush: jscript">var addTodo = function(todoText){
var deferred = $q.defer();
if(db === null){
deferred.reject("IndexDB is not opened yet!");
}
else{
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
lastIndex++;
var request = store.put({
"id": lastIndex,
"text": todoText
});
request.onsuccess = function(e) {
deferred.resolve();
};
request.onerror = function(e) {
console.log(e.value);
deferred.reject("Todo item couldn't be added!");
};
}
return deferred.promise;
};
</pre>
<br />
<br />
<span class="spanText">
Finally, the deleteTodo method accepts value of key property of the item to be deleted and invokes the delete method of the store to delete the item.
</span>
<br />
<br />
<pre class="brush: jscript">var deleteTodo = function(id){
var deferred = $q.defer();
if(db === null){
deferred.reject("IndexDB is not opened yet!");
}
else{
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
var request = store.delete(id);
request.onsuccess = function(e) {
deferred.resolve();
};
request.onerror = function(e) {
console.log(e.value);
deferred.reject("Todo item couldn't be deleted");
};
}
return deferred.promise;
};
</pre>
<br />
<br />
<span class="spanText">
Implementation of the controller is pretty straight forward. The controller invokes the members of the factory and updates the data items that are used to bind data on the UI.
</span>
<br />
<br />
<pre class="brush: jscript">app.controller('TodoController', function($window, indexedDBDataSvc){
var vm = this;
vm.todos=[];
vm.refreshList = function(){
indexedDBDataSvc.getTodos().then(function(data){
vm.todos=data;
}, function(err){
$window.alert(err);
});
};
vm.addTodo = function(){
indexedDBDataSvc.addTodo(vm.todoText).then(function(){
vm.refreshList();
vm.todoText="";
}, function(err){
$window.alert(err);
});
};
vm.deleteTodo = function(id){
indexedDBDataSvc.deleteTodo(id).then(function(){
vm.refreshList();
}, function(err){
$window.alert(err);
});
};
function init(){
indexedDBDataSvc.open().then(function(){
vm.refreshList();
});
}
init();
});
</pre>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3Q7JEjPQeuo62s4Hsl7i4XjwkcClM42KAt2ZmoWwD7soca6zP5lsHmaawoi_QUJjF6E0y1PkH5JFpsWjWjqOOMx35q1x-EWzmM9stzSav6P-B5zn146tphEbEYKmIcD88ofoj3Ak1Wc/s1600/todo.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3Q7JEjPQeuo62s4Hsl7i4XjwkcClM42KAt2ZmoWwD7soca6zP5lsHmaawoi_QUJjF6E0y1PkH5JFpsWjWjqOOMx35q1x-EWzmM9stzSav6P-B5zn146tphEbEYKmIcD88ofoj3Ak1Wc/s1600/todo.PNG" /></a>
<br />
<br />
<span class="spanText">
The complete sample is available on this plunk: <a href="http://plnkr.co/edit/7oSOUHC9hSnD8d6COkSK?p=preview" target="_blank">http://plnkr.co/edit/7oSOUHC9hSnD8d6COkSK?p=preview</a>
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com3tag:blogger.com,1999:blog-1007651349729494127.post-61085599975903543652014-01-26T13:00:00.002-08:002014-01-27T01:54:45.689-08:00Creating a Todo list using Indexed DB and Promise<div dir="ltr" style="text-align: left;" trbidi="on">
<style type="text/css">
.spanText{
font-family: "Calibri","sans-serif";
font-size: 11.0pt;
line-height: 115%;
mso-ansi-language: EN-IN;
mso-ascii-theme-font: minor-latin;
mso-bidi-font-family: "Times New Roman";
mso-bidi-language: AR-SA;
mso-bidi-theme-font: minor-bidi;
mso-fareast-font-family: Calibri;
mso-fareast-language: EN-US;
mso-fareast-theme-font: minor-latin;
mso-hansi-theme-font: minor-latin;
}
</style>
<br />
<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<b><u>What is Indexed DB</u></b>
<br />
<br />
HTML5 brought lots of capabilities to the browsers including some storage APIs. One of the storage options available on browsers today is Indexed DB. As the name itself suggests, Indexed DB is much like a database, but it is meant to store JavaScript objects. Data in the Indexed DB is not relational; it just has to follow a definite structure.
<br />
<br />
The browsers support a number of APIs to help us interact with the Index DB. Details about all of the Indexed DB API can be found on the <a href="https://developer.mozilla.org/en-US/docs/IndexedDB" target="_blank">Mozilla Developer Network</a>. Current implementation of the APIs by the browsers may not be perfect, as most of the APIs are still under development. But, the browsers have enough support now so that we can play around. Check <a href="http://www.caniuse.com/" target="_blank">caniuse.com</a> to find if your browser supports Indexed DB.
<br />
<br />
As <a href="https://developer.mozilla.org/en-US/docs/IndexedDB" target="_blank">API of the Indexed DB</a> says, all operations performed over Indexed DB are executed asynchronously. The operations don’t let the current thread processing to wait unless the operation is finished. Instead, we need to hook-up call backs to perform actions upon success or failure of the operation.
<br />
<br />
<b><u>Promises in the browser</u></b>
<br />
<br />
In the latest version of JavaScript, the language got built-in support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise?redirectlocale=en-US&redirectslug=Web%2FAPI%2FPromise" target="_blank">promises</a>. This means, we don’t need to use any of the third party libraries to prettify the asynchronous code and keep it clean from nasty call backs. As Indexed DB works asynchronously, we can use promise API to make the Indexed DB operations cleaner. Very few of the <a href="http://caniuse.com/#search=promise" target="_blank">browsers support</a> the promise API as of now. Hopefully others will join the club soon.
<br />
<br />
Using the promise API is very easy. But you need to have a good understanding of what promises are before proceeding further. Following snippet shows how to use the promise API in an asynchronous function:
</span>
<br />
<br />
<pre class="brush: jscript">function operate(){
var promise = new Promise(resolve, reject){
if(<some condition>){
resolve(data);
}
else{
reject(error);
}
};
return promise;
}
</pre>
<br />
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
Success and failure callbacks can be hooked up to the promise object returned in the above function. Following snippet shows this:
</span>
<br />
<br />
<pre class="brush: jscript">operate().then(function(data){
//Update UI
}, function(error){
//Handle the error
});
</pre>
<br />
<br />
<span class="spanText">
<b><u>Building a todo list app</u></b>
<br />
<br />
Let’s start implementing a simple todo list using Indexed DB. To store the todo items in the Indexed DB, we need to create an object store. While creating, we need to specify the version of the DB and the key property. Any object inserted into the object store must contain the key property. Following code shows how to create a DB store:
</span>
<br />
<br />
<pre class="brush: jscript">var open = function(){
var version = 1;
var promise = new Promise(function(resolve, reject){
//Opening the DB
var request = indexedDB.open("todoData", version);
//Handling onupgradeneeded
//Will be called if the database is new or the version is modified
request.onupgradeneeded = function(e) {
db = e.target.result;
e.target.transaction.onerror = indexedDB.onerror;
//Deleting DB if already exists
if(db.objectStoreNames.contains("todo")) {
db.deleteObjectStore("todo");
}
//Creating a new DB store with a paecified key property
var store = db.createObjectStore("todo",
{keyPath: "id"});
};
//If opening DB succeeds
request.onsuccess = function(e) {
db = e.target.result;
resolve();
};
//If DB couldn't be opened for some reason
request.onerror = function(e){
reject("Couldn't open DB");
};
});
return promise;
};
</pre>
<br />
<br />
<span class="spanText">
Now that the DB is opened, let’s extract all todo items (if exist) from it. The logic of fetching the items is conceptually similar to the way we do it with databases. Following are the steps:
<br />
</span><br />
<ol><span class="spanText">
<li>Open a cursor for the request to fetch items from lower bound</li>
<li>The items will be returned one by one. Handle appropriate call back and consolidate all the values</li>
</span></ol>
<span class="spanText">
Following code achieves this:
</span>
<br />
<br />
<pre class="brush: jscript">var getAllTodos = function() {
var todosArr = [];
//Creating a transaction object to perform Read/Write operations
var trans = db.transaction(["todo"], "readwrite");
//Getting a reference of the todo store
var store = trans.objectStore("todo");
//Wrapping all the logic inside a promise
var promise = new Promise(function(resolve, reject){
//Opening a cursor to fetch items from lower bound in the DB
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
//success callback
cursorRequest.onsuccess = function(e) {
var result = e.target.result;
//Resolving the promise with todo items when the result id empty
if(result === null || result === undefined){
resolve(todosArr);
}
//Pushing result into the todo list
else{
todosArr.push(result.value);
if(result.value.id > lastIndex){
lastIndex=result.value.id;
}
result.continue();
}
};
//Error callback
cursorRequest.onerror = function(e){
reject("Couldn't fetch items from the DB");
};
});
return promise;
};
</pre>
<br />
<br />
<span class="spanText">
To add a new item to the todo list, we need to invoke the put method on the store object. As mentioned earlier, key property should be present and it should be assigned with a unique value. So, we calculate value of the next id and assign it to the object.
</span>
<br />
<pre class="brush: jscript">var addTodo = function(todoText) {
//Creating a transaction object to perform read-write operations
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
lastIndex++;
//Wrapping logic inside a promise
var promise = new Promise(function(resolve, reject){
//Sending a request to add an item
var request = store.put({
"id": lastIndex,
"text": todoText
});
//success callback
request.onsuccess = function(e) {
resolve();
};
//error callback
request.onerror = function(e) {
console.log(e.value);
reject("Couldn't add the passed item");
};
});
return promise;
};
</pre>
<br />
<br />
<span class="spanText">
Finally, let’s delete todo item from the list. The logic remains quite similar to that of adding a new todo. The only difference is, we need just id of the item to be deleted.
</span>
<br />
<pre class="brush: jscript">var deleteTodo = function(id) {
var promise = new Promise(function(resolve, reject){
var trans = db.transaction(["todo"], "readwrite");
var store = trans.objectStore("todo");
var request = store.delete(id);
request.onsuccess = function(e) {
resolve();
};
request.onerror = function(e) {
console.log(e);
reject("Couldn't delete the item");
};
});
return promise;
};
</pre>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijIX3HxZYygK8ePjcSSCcVeWPCg9ikcLj9-GWS8BjydGuS3kH6fM3yj2Hg70hK-FlN1PVMoenXudtNqvflJL_GQBdV3GlhCbURNJ6b5noKkGgPgOBcl_s_c2ET9eAcpgflzNuTMNP7Eko/s1600/todo.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijIX3HxZYygK8ePjcSSCcVeWPCg9ikcLj9-GWS8BjydGuS3kH6fM3yj2Hg70hK-FlN1PVMoenXudtNqvflJL_GQBdV3GlhCbURNJ6b5noKkGgPgOBcl_s_c2ET9eAcpgflzNuTMNP7Eko/s1600/todo.PNG" /></a>
<br />
<br />
<span class="spanText">
Code of the complete sample is available at this plunk: <a href="http://plnkr.co/edit/aePFAaCucAKOXbb1qL85?p=preview" target="_blank">http://plnkr.co/edit/aePFAaCucAKOXbb1qL85?p=preview</a>
<br />
<br />
Happy coding!
</span>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-47501750055698883542014-01-21T11:43:00.001-08:002014-01-21T12:47:34.148-08:00SideWaffle and my Contribution to the Project<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<b><u>What is SideWaffle?</u></b>
<br />
<br /><a href="http://www.sidewaffle.com/" target="_blank">SideWaffle </a>is a community driven project that adds new project templates, item templates and code snippets to Visual Studio 2012 and 2013. It is a Visual Studio extension, can be installed from extension manager on both Visual Studio 2012 and 2013. If you are a .NET developer and use Visual Studio for development (which is obvious :)), install this extension before proceeding further.
<br />
<br />
The project is started by a set of folks including some working at Microsoft web tools team and some of the respectable technology experts. But the project is <a href="https://github.com/ligershark/side-waffle" target="_blank">open sourced on Github</a> and <a href="https://github.com/ligershark/side-waffle/pulls?direction=desc&page=1&sort=created&state=closed" target="_blank">accepts contributions</a> from any community member. If you ever wanted to see some templates of your own choice in the dialog boxed of Visual Studio, but were not sure of how to do it (like myself), now SideWaffle provides you a way to create the template very easily and also share it with all the developers around the globe.
<br />
<br />
<b><u>A glance at some of the templates and snippets</u></b>
<br />
<br />
SideWaffle already includes a bunch of useful templates and snippets. Following are some of the item templates available. As you see, we have a set of handy templates available to create just what we used to from scratch using the default language-based templates in Visual Studio.
</span>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDGYLnh_0goB5okTNh_aTalU9OznbgqXqOeawNlblNGp7hNmDzEGD4GlgZKFmhP_QXrrt_UX1_86QKYfSbSdjWz1tumkHtxCf7dNFxnULtxMckLwLNUrVG27Fc7qLfdHgIGZr79IPBZM/s1600/Item+Templates.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDGYLnh_0goB5okTNh_aTalU9OznbgqXqOeawNlblNGp7hNmDzEGD4GlgZKFmhP_QXrrt_UX1_86QKYfSbSdjWz1tumkHtxCf7dNFxnULtxMckLwLNUrVG27Fc7qLfdHgIGZr79IPBZM/s1600/Item+Templates.PNG" height="350" width="550" /></a></div>
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
You can also create non-.NET projects like Chrome extension using a project template made available with SideWaffle.
</span>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBMLdUlikoLzYYTiWRyb_bewm2XlYvdIewo2WX2ZuE_oxZn-a88udbWyGIzUGFsDp0yJFmUstx87S_kXRWeOuSPsyCY-idMuwpdjOuM28XeucNienySoYFp46sdy1ZpgYs6H3dcUCissQ/s1600/Project+Templates.PNG" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBMLdUlikoLzYYTiWRyb_bewm2XlYvdIewo2WX2ZuE_oxZn-a88udbWyGIzUGFsDp0yJFmUstx87S_kXRWeOuSPsyCY-idMuwpdjOuM28XeucNienySoYFp46sdy1ZpgYs6H3dcUCissQ/s1600/Project+Templates.PNG" width="550" /></a>
<br />
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<b><u>My contribution</u></b>
<br />
<br />
Over the past few days, I have been unit testing some Angular JS code. Creating the test spec files from scratch every time was not something I enjoyed. So, I wanted to see templates in the Add -> New Item dialog box of Visual Studio that creates a basic test skeleton on top of which I can write my tests. In the past, I have used Jasmine and QUnit for unit testing JavaScript code. So, I thought of contributing the templates to SiddeWaffle as testing JavaScript is becoming very popular these days. I forked the SideWaffle project on Github and my job of writing templates became easy with help of the <a href="http://youtu.be/naY3jbBNNgY" target="_blank">video tutorial put up by Sayed on Youtube</a>. I created the following four templates:
<br />
<br />
1. Jasmine Spec and HTML files: Adds a sample Jasmine spec file and the Jasmine HTML runner file
2. Jasmine Spec file: Adds a sample Jasmine spec file
3. QUnit Spec and HTML files: Adds a sample QUnit spec file and the QUnit HTML runner file
4. QUnit Spec file: Adds a sample QUnit spec file
<br />
<br />
I sent a <a href="https://github.com/ligershark/side-waffle/pull/84" target="_blank">pull request</a> with the above templates and my changes were merged into the project. Now, I can’t wait to see my own templates under the SideWaffle tab:
</span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMjHIuu2Uaw_C6F4VrGZ6asSn0I_A2dZlDspWwRiZaE-BBiI279er3_x_9Xv5YGeDnqfOrrT3XoQbzdlsCUPAEIFRPQm0WI-KK_Mk_ds5v73ogz6eYNs7XmoTE92TSUsC9sbInbzD3T0Q/s1600/MyTemplates.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMjHIuu2Uaw_C6F4VrGZ6asSn0I_A2dZlDspWwRiZaE-BBiI279er3_x_9Xv5YGeDnqfOrrT3XoQbzdlsCUPAEIFRPQm0WI-KK_Mk_ds5v73ogz6eYNs7XmoTE92TSUsC9sbInbzD3T0Q/s1600/MyTemplates.png" /></a>
<br />
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<b><u>You can do it too!</u></b>
<br />
<br />
I have put together this blog post to let you know people like you and I can create our own template and share it with the entire community. Creating own item template in Visual Studio is painful, but SideWaffle’s build system makes this process very easy. Have a template that you want to share with everyone? Put it <a href="https://github.com/ligershark/side-waffle" target="_blank">here</a>!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com0tag:blogger.com,1999:blog-1007651349729494127.post-45908370211245547302014-01-07T12:47:00.001-08:002014-01-07T12:47:31.586-08:00Using Dependency Injection with ASP.NET Web API Hosted on Katana<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
Using Katana we can build a light-weight server to host an ASP.NET application, without needing IIS or System.Web. Katana has a nice support for hosting SignalR and Web API with very few lines of code. In a previous post, we saw how to <a href="http://sravi-kiran.blogspot.com/2013/12/SelfHostingAspNetSignalRUsingKatana.html" target="_blank">self-host SignalR using Katana</a>. In this post, we will see how easy it is to perform dependency injection on a self-hosted Katana application.
<br />
<br />
Open Visual Studio 2013 and create a new console application. Add following NuGet packages to the application:
<br />
<br />
</span><br />
<ul><span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<li>Install-Package Microsoft.AspNet.WebApi.Owin</li>
<li>Install-Package Ninject</li>
</span></ul>
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<br />
<br />
First package gets a bunch of packages for creating and hosting Web API. The second package installs the <a href="http://www.ninject.org/" target="_blank">Ninject IoC container</a>.
<br />
<br />
Add an API Controller to the application and change the code of the controller to:
</span>
<br />
<pre class="brush: csharp">public class ProductsController : ApiController
{
IProductsRepository repository;
public ProductsController(IProductsRepository _repository)
{
repository = _repository;
}
public IEnumerable<Product> Get()
{
return repository.GetAllProducts();
}
}
</pre>
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
We need to inject instance of a concrete implementation of IProductRepository. We will do this using dependency injection. You can create the repository interface and an implementation class by your own.
<br />
<br />
To perform dependency injection with Web API, the WebApiContrib project has a set of NuGet packages, including one for Ninject. But the version of Web API it requires is 4.0.30319. As we are using VS 2013, the default version of Web API is 5.0.0.0. Installing this NuGet package may result into version compatibility issues. To avoid this issue, we can build the WebapiContrib.Ioc.Ninject project using VS 2013 or we can also copy the code of <a href="https://github.com/WebApiContrib/WebApiContrib.IoC.Ninject/blob/master/src/WebApiContrib.IoC.Ninject/NinjectResolver.cs" target="_blank">NinjectResolver class from the GitHub repo</a> and add it to the console application.
<br />
<br />
In the Owin Startup class, we need to configure Web API and also tie it with an instance of NinjectResolver. Constructor of NinjectResolver accepts an argument of IKernel type. Kernel is the object where we define the mapping between requested types and types to be returned. Let’s create a class with a static method; this method will create the kernel for us. Add a class and name it NinjectConfig. Change code of the class as:
</span>
<br />
<pre class="brush: csharp">public static class NinjectConfig
{
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<IProductsRepository>().To<ProductRepository>();
return kernel;
}
catch (Exception)
{
throw;
}
}
}
</pre>
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
Now all we need to do is, configure Web API and start the server. Add a class, change the name as Startup and replace the code as:
</span>
<br />
<pre class="brush: csharp">public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.DependencyResolver = new NinjectResolver(NinjectConfig.CreateKernel());
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id=RouteParameter.Optional });
app.UseWebApi(config);
}
}
</pre>
<br />
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
Finally, start the server in Main method:
</span>
<br />
<pre class="brush: csharp">static void Main(string[] args)
{
string uri = "http://localhost:8080/";
using (WebApp.Start<Startup>(uri))
{
Console.WriteLine("Server started...");
Console.ReadKey();
Console.WriteLine("Server stopped!");
}
}
</pre>
<br />
<br />
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
Open a browser and enter the following URL:
<br /><br />
</span><br />
<center>
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">http://localhost:8080/api/products</span></center>
<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-IN; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">
<br />
<br />
You should be able to see list of products returned from the repository class.
<br />
<br />
Happy coding!
</span>
</div>
Anonymoushttp://www.blogger.com/profile/14704377348226567479noreply@blogger.com2