Wednesday, November 4, 2015

Getting Inside Angular: Can a Digest Continue Forever?


No, but let's look at why.

It is very plausible that you could create a situation where a series of watchers that made changes to the scope would lead to the current digest cycle continuing forever. When performing a $digest, all the watchers are checked for changes and only when no changes are detected, does the digest end (from a high level this is true, but the actual change detection algorithm is optimized so that the final cycle is terminated early when it reaches the last watcher that registered a change). During each cycle, if at least one change is made to an attribute that is being watched, this would lead to a never ending digest as one change would trigger another and so on. Luckily the Angular team thought of this!

TTL:

Time To Live is the mechanism that keeps a record of how many cycles the digest has performed and will end the current digest if is reaches its 11th; in other words, a digest will terminate if it exceeds 10 cycles.

A simple way to create a situation where a watched attribute is being changed with each cycle of a digest is to use a counter and have the listener function increment its value:

$scope.counter = 0;
var removeWatch = $scope.$watch(
  function (scope) { return scope.counter; },
  function (newValue, oldValue, scope) { scope.counter++; }
);

After 10 cycles, the digest cycle terminates and an error is generated:


Details of the watchers that were fired in the last five iterations are included to help identify what caused the digest to continue to the TTL limit.

Any undetected changes will remain so until the next digest is run. No future digest is scheduled in this situation as that would essentially be a continuation of the current digest. It is also worth noting that the $$postDigest queue is not flushed when a digest is terminated and won't be until the next digest cycle successfully ends.

View on Plunker (open the developer tool's console).

You'll probably never run into this scenario, but it's good to know that the digest has got your back!

//Code, rinse, repeat

Tuesday, October 13, 2015

Why YOU Need to Read Other People's Code

Take a moment to sit back in your chair and think over the past week. How much coding did you do? And of that, how much was actual greenfield development? How much of your past week involved you working with code that was written by someone else or even by yourself but over six months ago (let's face it, if it was written by you six months ago, then it might as well have been written by another person!)?

I believe it's pretty obvious to say that there is more code out there in production than there is being created. What this means is that there's a lot more code that needs to be maintained on a daily basis than there is being created anew. An enterprise developer might get the opportunity to work on something new, but it is more than likely to be a new feature for an existing application. The constraints and API of the current application will determine the architecture of this new feature and this will be determined from either good documentation (how many places have that?) or reading code.

I frequently hear "I'm not sure how that works. I'll have to go through the code" or something similar at where I work. I feel that more time is spent reading code written by another than is actually writing code. If such a large amount of our working day is spent reading code, shouldn't we look to devote some of our "sharpening the saw" time to developing our skill to do this? Writing code is easy but reading code is harder because you have no idea what the programmer was thinking at the time they wrote it! Spending some time sharpening your skills in this area would be both beneficial to yourself and your team.

There are also other benefits from reading code that was written by someone else than you:
  • You get to see how someone else approached a problem: this insight could help you the next time you face a similar problem
  • You will more than likely learn something: we don't know everything so this could be something to do with the programming language, framework, business domain, or coding style of the author.
  • Reading other people's code will make you more aware that someone else might read your code in the future
Where to go from here?

With open source, it couldn't be easier to start reading code written by someone else. There is lot of code out there (both good and bad) so it shouldn't be hard to find a project that interests you. Jumping straight into the Angular code base probably isn't the best place to start and I would recommend starting with a something smaller that aims to solve a very simple and narrow problem. 

Something to keep in mind is just because you don't understand the code, that doesn't necessarily mean the author is smarter than you so don't let this discourage you! A section of difficult to understand code is a potential opportunity to refactor. I doubt you are alone so making it easier to understand would be a great way to contribute to the project.

And remember the next time you start writing some code, it's probably going to be someone else who is going to have to maintain it!

//Code, rinse and repeat

Wednesday, September 16, 2015

Debugging your Seed method when running Entity Framework's Update-Database Powershell command

Sometimes when running the Update-Database Powershell command when using Entity Framework's Code First development model, you can have an exception generated within your Seed method. Sadly, this is only communicated to you via the Powershell window:


By default, as the Seed method is not being executed within a context which has a debugger attached, there is no way to interact with the exception as it occurs or set a break point within the Seed method to step through the code as it executes.

Wouldn't it be nice if you could take advantage of Visual Studio's debugger and interact with the code within the Seed method to get to the bottom of that pesky exception? Thankfully this is possible with a little bit of custom code that instantiates a new debugger if one is not already attached. Using code to instantiate a new debugger?! Surely this is not possible I hear you asking... I did not know this was possible either until I hit this problem and this piece of code made me smile, ALOT!

if (System.Diagnostics.Debugger.IsAttached == false)
  System.Diagnostics.Debugger.Launch();

That is all there is to it. This code will determine if a debugger is already attached to your execution context. If not, a dialog is displayed allowing you to select what debugger you would like to attach:


As you can see from the capture above, you have the option of opening a new instance of Visual Studio to debug in or not opening a debugger at all. Note, you can also specify the version of Visual Studio you want to use. How cool is that? Hold on, it gets better.

If you select to debug in a new instance of Visual Studio 2013, Configuration.cs will open in a new window and display the warmly welcomed user-unhanded exception dialog as it occurs within the Seed method:


From here you have all the familiar functionality to drill into the exception details to determine what went wrong. Nice. There is still more though.

You can even set a break point in the debug instance of Visual Studio within the Seed method and step through the code as it executes:



Now that is seriously cool.

I generally add this piece of code to the top of my Seed method so the magic can happen whenever I execute the Update-Database Powershell command. However, if you are updating your data model frequently, you may only want to include this code when you have a problem with the Seed method (or any other code being executed as part of the Update-Database process).

You can find a project here which illustrates this in action. All you will need to do is open it in Visual Studio 2013, build it to restore the packages (ensure you have NuGet version 2.7+ installed - see here for why) and run Update-Database from the Package Manager Console.

Tuesday, September 8, 2015

Getting Inside Angular: $scope.$evalAsync

If you want something to be executed while a digest is in progress, then $scope.$evalAsync is probably what you're looking for.

What does $scope.$evalAsync do?

When a digest is in progress, Angular is looping through all the watches and comparing values to detect if any changes have occurred. As the listener function from a watch could cause a change to another watched property, this loop can run multiple times per digest. $scope.$evalAsync adds the supplied function to a queue that will be drained at the beginning of the next loop in a digest cycle. It won't wait for the current digest cycle to complete but will execute the $evalAsync'ed function before starting the next loop through all the watches. If a digest is not in progress, one will be scheduled when a function is added to the async queue.

When would you want to use it?

A good explanation of when you would want to use $scope.$evalAsync can be found here: http://stackoverflow.com/questions/17301572/angularjs-evalasync-vs-timeout

In summary, as it queues work to occur outside of the current stack frame:
  • In a Controller: it will run before the DOM has been manipulated by Angular (take caution as your change could be overwritten) and therefore, before the browser renders
  • In a Service: it will run after the DOM has been manipulated by Angular but before the browser renders
If your change is going to affect something that is being rendered, $evalAsync will prevent a flicker from occurring as its work will occur before rendering.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  
  $scope.$watch(
    function (scope) { return scope.name; },
    function (newValue, oldValue, scope) {
      
      console.log('First watch executed \nAdding $evalAsync');
      scope.$evalAsync(function (scope) {
        
        console.log('$evalAsync executed');
        scope.newValue = "new value!";
      });
    }
  );
  
  $scope.$$postDigest(function () {
    
    console.log('$$postDigest executed. Digest completed');
    console.log($scope.newValue);
  });
});

View on Plunker (open the developer tool's console).

The above example ensures that $evalAsync is being called (line 9) during a digest by calling it in the listener function of a watch. The work that is being added to the async queue logs a message out to the console to indicate that the work has been executed and then updates a value on the scope. Line 17 adds a function to the post digest queue* to indicate when the digest has completed.

From the output it is clear to see that the function that was added to the async queue was in fact executed during the already in progress digest.

*The post digest queue is drained once all the change detection loops of the watches have completed and is the last step of a digest that you can interact with. However, the Angular team would prefer that you don't use it--or that you take great care if you do--by marking the $$postDigest function private by prefixing it with two dollar signs.

Performance considerations

Adding to the async queue is either going to cause a new digest to occur or if one is in progress, for it to loop one more time through the watches. If the queued work causes changes to other properties that are under watch, this will lead to additional loops. Angular has a mechanism to prevent a digest from continuing forever and will only allow 10 loops to occur before the digest is terminated (known as TTL: Time To Live). As you cannot control at what point during a digest (in other words, how many loops it has already performed) your work is being added, it could be approaching its TTL limit. This is something to consider when using $evalAsync.

Versus $scope.$applyAsync

Both $applyAsync and $evalAsync are tools that help you get around "$digest already in progress" errors. In my opinion, $applyAsync is the safer option as this queue will be flushed before a new digest begins. This will reduce the likelihood that your work will cause a digest to be terminated due to reaching the TTL limit. There is the potential though that using $applyAsync will cause a flicker as you will be relinquishing control back to the browser before your queued work is executed. If the browser decides to render first, then a flicker could occur. Some might prefer $evalAsync for this reason as it won't leave them at the mercy of the browser's event loop.

//Code, rinse, repeat

Tuesday, August 25, 2015

Getting Inside Angular: $scope.$applyAsync

Have you ever used $scope.$apply and received a "$digest already in progress" error? If so, $scope.$applyAsync might be what you should be using!


What is $apply actually doing?

The most common reason to use $apply is when something is happening outside the scope of Angular and you want Angular to react to any changes that have occurred. $apply is your way of instructing Angular that something has happened and that it needs to go through its change detection routine--in other words, perform another digest. You might have noticed that "digest" was also mentioned in error message. This is no coincidence.

When you call $apply, it first executes the function that was supplied and then immediately starts a new digest cycle. In preparation to start a new digest, it checks that one is not already in progress before doing anything and if one is, the above exception is thrown. This can be somewhat jarring because you have little control over when Angular is performing a digest.

What’s the solution?

A common solution that I've seen is based on the fact that the function you want to $apply doesn't actually have to be "applied" at this moment in time and can wait to be executed at some point in the very near future. This is achieved by wrapping the $apply statement in a setTimeout with a very small timeout value, normally zero:

setTimeout(function () {

  $scope.$apply(function () {
   
    console.log('This will also work as you are using setTimeout');
  });
}, 0);

While this is all and good and will solve this issue in the majority of cases, there happens to be a more efficient mechanism already built into angular: $scope.$applyAsync!

Note: If the supplied function needs to been executed during the already in progress digest cycle, $evalAsync is probably what you're looking for.

$scope.$applyAsync

$applyAsync looks the same as $apply, but instead of starting a new digest immediately, it will schedule one to start in the very near future. The benefit of using $applyAsync over wrapping $apply in your own timeout, is when another digest cycle starts before the one that you scheduled does. If this happens, then the function supplied to $applyAsync will be executed before the change detection routine starts; when this wouldn't be the case If you had used your own timeout. The order of execution is up to the browser to decide what is next so by using $applyAsync, you are guaranteed that your function will be executed during the next new digest.

Example:

app.controller('MainCtrl', function($scope) {
  
  $scope.$watch(function () { },
    function (newValue, oldValue, scope) { 
      
      scope.$apply(function () {
        
        console.log('This will not work');
      });
    }
  );
    
  $scope.$watch(function () { },
    function (newValue, oldValue, scope) { 
      
      scope.$applyAsync(function () {
        
        console.log('This will work as you are using $applyAsync!');
      });
    }
  );
}); 

View on Plunker (open the developer tool's console).

The above code shows one example where a $apply is being called during a digest cycle which will result in a "$digest already in progress" error (open the developer tool's console to see this). The second example uses $applyAsync and the message "This will work as you are using $applyAsync!" will appear in the console.

//Code, rinse, repeat

Monday, July 27, 2015

How to Use Bootstrap (CSS only) and Webpack

I thought it was going to be easy.

require("bootstrap-webpack");

I thought that with a single line of JavaScript, I could have Bootstrap available for use within my web application. However, that was not to be the case. After battling through Webpack producing errors about CSS, woff2 and various other issues, I finally reached my limit at:

Uncaught ReferenceError: jQuery is not defined

I'm sure I'm not the first person to run into this issue (a quick Google produced this solution) but what pushed me over the edge was that I only wanted Bootstrap for it's CSS; I had no need to add jQuery as I wasn't going to use any of Bootstrap's JavaScriptiness. As far as I was concerned, this was another hoop and I wasn't going to jump through it.

With invigorated motivation and a fierce sense of purpose, I set out to get Webpack running with Bootstrap's CSS and nothing more. There had to be a way where I could load bootstrap.min.css and that is what I sought out. 


From my previous attempts to use bootstrap-webpack, I felt that if I had the correct Webpack loaders installed and configured correctly, Webpack should be able to load the CSS file. After playing around with adding and removing loaders, I settled on five that appear to be the bear minimum you need:
  • babel-loader: to transpile the "require" keyword
  • css-loader & style-loader: for processing CSS
  • file-loader: for handling "eot" resources
  • url-loader: for handling woff, woff2, ttf & svg resources

I expect that as Bootstrap evolves, this set of loaders will change but as of v3.3.5, these are all you need.

webpack.config.js:

module.exports = {
    entry: {
        app: ["webpack/hot/dev-server", "./app/app.js"],
    },
    output: {    
        path: './app',
        filename: 'bundle.js'
    },
    module: {
      loaders: [
            { test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel' },
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
            { test: /\.(woff|woff2)$/, loader:"url?prefix=font/&limit=5000" },
            { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
            { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }
      ]
    }
};

The loaders were configured as above. Most of this was extracted from the configuration for bootstrap-webpack. The only change of note was updating the test for the url-loader to match both woff and woff2.

This solution is perfect for use with an Angular application where you are using angular.ui. Adding Bootstrap's JavaScript and jQuery in this scenario would be a waste as angular.ui provides the same set of features. 


Oh, and with the Babel-loader installed, you are free to use ES6 to your heart's content!

Feel free to check out the repo on GitHub

//Code, rinse, repeat

Monday, July 20, 2015

The Importance of a Pet Project

A pet project is a great way to learn a new technology or get a better understanding of one you are familiar with already. It’s also a fun way to learn.

Here are a few “rules” I have found along the way after having nurtured a few pet projects of my own:
  1. Come up with a project that is not too big or complex. I want to be able to concentrate on exploring the technology instead of battling with the complexities of the project itself.
  2. The more fun a project is, the better chance you have at actually making good progress with it. As you are doing this in your own time, you want something that is interesting to keep you motivated otherwise it is too easy to find something else that needs to be done instead.
  3. Aim to build something that has a well defined feature set. It is too easy to start playing with a technology without an end goal in mind. By setting yourself some goals or features, it forces you to look at utilizing the technology with an end goal in mind.
  4. Be prepared to learn more than you expect – More on this below.
  5. Share what you have built. Sharing the end product with your peers is an excellent way to get some additional learning miles out of your pet project and new ideas.
The biggest surprise I constantly find is that I end up learning a lot more than I envisaged at the start of the project. For example, my latest pet project (Sharpen the Dev Saw) I wanted to learn more about building a client-side JavaScript app and responsive design using Bootstrap. When I sat back at the end of the project and looked at what I had actually covered, it was a lot more:
  • Working with Knockout.js
  • JavaScript design patterns (MVVM, Revealing Module)
  • A better understanding of JavaScript as more than a scripting language.
  • CSS 3 animations using animate.css
  • CSS 3 transitions for hover states
  • Unit testing JavaScript using Jasmine
  • Working without JQuery
  • Flat UI web design
  • Displaying information concisely when using a Flat UI design
  • Modern input interactions using CSS animations
  • Using a light weight IDE - Brackets
  • Using Grunt as a build automation tool
  • Auto-deploying to Azure using Git and Grunt
As you can see, that is quite a list and I probably have missed some items off there as well.

Sharpen the Dev Saw was a straight forward pet project. As a keen believer in Continuous Learning, I am sometimes asked how you fit continuous learning into daily life. I used to explain that 30 minutes a day does not sound like much each day but over the course of a year it adds up to quite a lot of learning. I usually then had to do the sums to back this up (it’s 10950 minutes or 183 hours a year!). I wanted an app that visually displayed this and then gave some examples of what you could achieve with this time. Hence, Sharpen the Dev Saw was born. As the project itself was simple I was able to concentrate on exploring technologies to get it to work how I wanted instead of becoming bogged down with project complexities.



My pet project prior to Sharpen the Dev Saw was an online portfolio site. I originally planned to build a standard portfolio site using a master-detail design. In the end, I went with a totally different design and learnt about building Parallax Scrolling sites instead. Feel free to check it out here.



Another pet project came following a chat I had with a senior manager at a previous employer. They wanted to make a project’s or software release cycle’s progress more visible as all the stats were buried in Team Foundation Server. This chat lead to me building MVC Dashboard as a demo dashboard app with a Metro design. You can see MVC Dashboard here.



So what’s next? I would like to add some automated UI tests to the deployment pipeline for Sharpen the Dev Saw which are run once the deployment to Azure is complete. Also, I wouldn't mind looking into re-writing Sharpen the Dev Saw using TypeScript too. However, my next pet project is calling - a Continuous Learning Management app built with AngularJS and ASP.NET WebAPI. Here comes the sales pitch… Ever spent hours hunting for that blog post you read months ago but could really do with finding now? Want to make all the self study and development you do in your own time more visible?  Have you wondered what tech areas you have spent the last few months looking in to? This could be the app for you. I am hoping it will be an app that will allow you to track what you are learning and gain insights to help you steer your learning efforts in the direction you want. More on this another time though. (It’s an ambitious project and probably breaks rule 1 – Doh!)

You can find the source code for the pet projects mentioned in this blog post here:

Nurture your pet project, it’s an excellent learning tool.