April 17, 2014

Printing a Dialog content using Canvas and iFrame

Hi guys,
You know that printing from the browser is a bitch. Even after you've figured out how to put the content you want into the browser, the printing doesn't always work the same on all the browsers (yes! HTML is a standard... my arse). And that's not where all the trouble stop but anyway...

The problem I would like to bring up in this post is printing from a dialog box, which is more complex since we have to somehow extract the visual data from the dialog and then put it in some way that the crippled window.print() method can make sense of it. I mean seriously, have you ever seen such a lame API? print()? that's it? no "what do you want to print?". Throw me a freaking bone here.
Given that we're dealing with a dialog kinda eliminates the possibility to use the print media query, since we're not going to alter the whole page, just a section of it.

I saw many solutions on the web, some offering to save and then clean up the DOM, attach a cloned version of the DOM you actually want to print, and then re-render it all back after printing, which to me sounds like "bla bla bla bad performance sad users bla bla bla".
You know, all kinds of adding classes to elements, removing it then later... oh god.
Of course there is the jQuery plugin which offers to do that but I wasn't in the mode to introduce yet another jQuery pluging so I had to think of something else...

Canvas came to the rescue.
The idea I came up with is to somehow capture the DOM content I wanted to print, convert it into an image, and then create a hidden iFrame bearing the content of this image among other stuff I wanted to be printed. How? canvas can be concerted into an image.
I already had html2canvas library so it wasn't in a need to download any other 3rd party. you can get what it does from it's name, right? good.

Moving forward, here's the actions the code needed to perform (pseudo-code):
  • Get the canvas from the HTML elements
  • Convert the canvas to an image using the toDataURL('image/png') method
  • Create an iFrame dynamically
  • Append the iFrame to the DOM 
  • Once loaded Set the iframe content with the newly generated image I have
  • Send it to printing, by printing the iFrame content only
  • Smoke a cigarette
I believe that what's written above should give a good idea on how to implement it.
As for printing the iFrame itself I took a code snippet from some stackoverflow thread but I had to tweak it a bit since Firefox didn't like what I did, for it removed the iFrame before the browser launched it's printing. To overcome this I've used a deferred object, like so:

this.printIframe = function (id) {
var deferred = $q.defer(),
    iframe = $window.frames ? $window.frames[id] : $window.getElementById(id),
    ifWin = iframe.contentWindow || iframe;
ifWin.focus();
ifWin.print();
deferred.resolve('done');
return deferred.promise;
};

and this means that I had to listen to the promise in order to remove the iframe from the DOM and not just count on the fact the window.print() is supposed to stop javascript execution...

I think that pretty much sums it up. It might not be the best idea out there so I would love to hear your opinion on it or better if you have a better one.

… and BTW -
I caught this nice AngularJS Weekly magazine (or whatever you would like to call it) on the way. A lot of cool resources and stuff. Pretty nice.

Stay tuned and play on.

April 12, 2014

All the JS you need

Yo guys,
You know me, I'm just strolling around the web bumping into nice stuff on the way, and recently I found a great place where you can pretty much get all the knowledge sources you need for JS.
To be honest, it's pretty amazing how much one can gather about this Egyptian-pyramids-fucking-papyrus-deserved scripting language, but then again we must, now don't we? :)

Enjoy it: superhero.js

April 07, 2014

Delegating Event handlers to align Event Data model


After such a pretentious title we can all stop and take a one week sleep. WTF do I want from you now, you probably ask. yeah, ok. check this out:

Think about this next situation - You have a nice component which potentially can host several other components, each can dispatch a different event, an event that needs to be handled of within the "parent" component.
We cannot let the "parent" component manage all the events potentially fired from its nested components, right? I mean, we can let it but then we will pretty much shit into our own development experience and maintenance, after all, we want the "parent" component to be aware of a single Event data model.

Being aware of a single event data model means that the "parent" component will expect a single format of data when receiving events from any of its nested components. It will not matter what's the data model of each nested component, something will have to align it into a single well-known model. The question is who?

We need some kind of a delegator, which will know all the potential events and will process their data and send a nice formatted data back to the "parent" component.
So, if we are to drill into more details, we're actually talking about extending the "parent" component's Scope, since it is that Scope which will eventually listen to all these events, but it will be done in a sort of a "mixin" approach.
The solution I came up with introduces a service which has a single method registering the "parent" component's scope. From there on, the service will extend the Scope and eventually send an event back to the "Parent" component with the processed event data.
Simple does it.
 
The POC can be found in Plunker

I would love to hear if you have any comments about it.
Cheers

April 03, 2014

My Unit Testing Approach to JavaScript

Hi guys,

I thought it would be nice to share with you my approach to JavaScript unit testing.
It's not really bound to any particular technology so you can embrace it if you think it can bring you some peace.
  • Configure a threshold time of each test to be less than 500ms. I hate to wait on code. I need feedback now.
  • I feel really bad when I need to write test for a already written code. It misses the whole purpose and usually results in bad testing. I thrive to always write tests first and code later. Close the gap you have, and start working the right way.
  • Start from high-level "it"s describing what you want to test do check, so the result will be a set of empty "it" functions describing the expected functionality.
  • Launch a watcher on the test files. This is crucial for having immediate feedback to whatever you're writing.
    • For me, I launch the grunt serve task (Yeoman) which let's me see the application running while monitoring the tests. The Karma runs as a part of it and while keeping the autoWatch parameter as true, each save is triggering the tests. I'm always testing and seeing that the application doesn't break.
  • Writing minimal code to fix the test is so important. We, developers and mostly architects, have the tendency to think far and beyond. Stop it. I'm fixing only what is required. At least I try to… ;)
  • If I see that a group of tests should be bound together under some functional context, I do that by adding nested "describe"s.
  • I'm always making sure that the description for the tests make sense as a real sentence which anybody can understand, even fishmongers.
  • Test is first citizen code. Have JSHint/JSLint prob on your test code as well. 
  • I want to see my coverage all the time. It gives me satisfactory and a warm pat on the back, but seriously now, I got to have some indication as to how good am I doing and whether I cover all the branches important to me. 

Do you have a different approach?

… and BTW -
I've bumped into this nice online tool which helps assessing 3rd party JS libraries.
Check it out at jscritic

Stay tuned.

April 01, 2014

Mocking a Confirmation Dialog in AngularJS Unit-Testing


What is more convenient then talking about the shallow gratification tests give us in the previous post, and now posting about testing examples. What can I say, you got me, I'm a child ;)

Anyhow, lets take the following case: User wishes to delete some book from his library, once he presses the delete button a confirmation dialog pops up to ask him if he is stupid or not, and once he approve that he is, the entity is being deleted.

Now, some of you may jump and shout that this is no unit! this is an automation test par excellence, but I would have to shut them up and say that yeah, this should also be tested in automation but there are unit aspects that need to be checked as well. let me explain-
You controller will probably contain 2 methods:
  • confirmBookDeletion - which pops the dialog
  • deleteBook - which actually deletes the book
In my unit testing I would like to cover both methods. so basically, the "deleteBook" is the easy one, where you simply expect DELETE on you $httpBackend, but the tricky one is the confirmation.

If we will break it down, the process is: display a dialog with a certain caption to it, wait for that dialog "promise" and act according to the decision (in our case "yes" invokes the deletBook method).
how do you do that? that's right, you mock it. but how?

Obviously you have some sort of a DialogService which makes your work mach easier, and on it you have a nice "confirm(msg)" method which does what take, but how exactly are you going to mock it? it's not just making sure that DialogService.confirm(msg) was called but it has to return a promise which you can later work with. It's actually pretty straight forward

First thing, let's create a MockDialogService. We do that for the sake of spying after it's confirm method:
MockDialogService = {
confirm: function(msg) {
}
};

So now you can spy on this method, but here is the nice trick - by spying on it you can define what returns when you call it, and in our case we would like to return a resolved promise with the value of "yes" (cause this is what we're testing now):
var deferred = $q.defer();
deferred.resolve('yes');
spyOn(MockDialogService, 'confirm').andReturn({result:deferred.promise});

Now that we have that we can make our expectation from it, like so:
expect(MockDialogService.confirm).toHaveBeenCalledWith('Are you out of your mind?!');

Nice. Now we need to see how this invokes the deleteBook method. so we spy on it:
spyOn(yourCtrl, 'deleteBook');

And here comes the tricky part. Since promises will be executed on the next Angular Digest cycle, we need to trigger it. We do this with scope.$apply(). After that we can expect that the deleteBook() method will be called:
scope.$apply();
expect(ctrl.deleteBook).toHaveBeenCalled();


Cheers

March 26, 2014

Understand why

So - You writing code in a TDD manner, which means that basically you're writing the tests first, waiting on them to fail, and then writing the code which makes them pass.
Damn, This makes you feel so good, right? It's like a fucking rush of satisfactory that runs through you, making you feel like you're fulfilling your roll in the world, you're executing your work to the max. You tell yourself that hey! You can do that forever. No, seriously - FOREVER.
But have you ever wondered why you feel this way?

What exactly taps into our, some-might-claim, childish emotions and pats us so warmly on the back?
Most of us feel this way and usually don't give a flying fuck about the end product, not to mention the end user of the software their creating, and this puzzles me greatly - what makes some of the smartest people I know develop such an addiction to this an immediate, shallow gratification feeling?

Let me try to ware the psychoanalyst hat for a sec and make some assumption on why a developer feels so good about a passing test and try to drilldown to find the true nature behind this behavior

Is it the quality?
Sadly I would have to say it is rarely the quality increase which makes developers so satisfied with a passing test. I saw many tests which don't check anything and pass successfully, leaving their author happy like pig-in-shit with the work he has done. In some cases developers would even knowingly cheat to make a test pass, although they will later claim that this has damaged their satisfaction since our conscience cannot be tricked that easily. Sadly The build can.
Personally I believe that the motivation for tests should come from the desire for quality. Why you desire quality? Because you want your customers to enjoy and have value from using your product.

Is it the game?
Writing software in TDD is very much like playing a self-game. It's like you're challenging yourself, much like playing Solitaire, putting targets and then trying to hit them with a stone from afar. And you have monitoring which kind of represent a leader board where you can see how much targets you did hit (coverage), which sometimes brings developer to an absurd state where their testing meaningless chunks of code like Getter/Setter just to have their coverage up.
The game does have contribution to developers satisfactory, but playing it without seeing the big picture can sometimes distract you from the real goal, that is making the end product better for the user. After all, all your code can be covered with tests and you will be top of the list, but the product doesn't sell because it is a piece of crap. Better start packing your cubical up cause your company went broke, but hey, don't forget to take the leader board with you!

Is it the mini-goals?
You know these lovely "todo" lists? Research have shown that people enjoy "checking" a task as done so much, that sometimes they register task they've already completed just to have a "check" next to it, while other tasks that really needs to be attended are left neglected. You know what I'm talking about… yes, you do.
Same with the tests. You set up small tasks to be completed, e.g. "should fetch user information" and you right away start working on it in order to put a "check" over it. You like it so much that sometime your tests become meaningless and have no benefit to the code quality or maintenance.

Is it our perfectionism?
You love to see thing done to perfection. Most of us who deal with software do (some don't and they should get fired. I mean - now). So you look at your coverage report and you eye starts to twitch for you see that you're missing 3% to your 100% code coverage. You don't mind that the code is well tested and that 3% is redundant and having them tested will not benefit the code whatsoever. You want to reach that 100%. A sheer waste of your time and build time, but damn - I just have to get this thing 100% green.

Tests are not the goal, they are the means
Yeah, let's remind ourselves once again that tests are the means in getting our goal which is a good and maintainable product releases. No seriously, you have to stop dancing around glorifying the hammer you're holding when all you have built with it is a huge pile of horseshit.
And for that matter, I strongly believe that developers should stop alienating themselves from the product. It's not only the tests which are the means but the code itself. It is your means for creation. The paint of your brash, the nail and hammer. We should concentrate on the painting. You have never seen a child showing off his color palate to his parents, right?

So why then?
Because it's easy and well defined.
If you look closely at the tasks you've recently had you'll find it that you tend to avoid those which are hard to complete or those which you have a vague idea on how to accomplish them. Tests are neither. Tests are well defined tasks which are basically easy to complete. Of course you like doing them. Hell, you're even get credits if you make a lot of them.
Why the hell won't you write them like crazy?

Conclusion
Tests are good. Write them. Responsively.
You're not a monkey. Always question the world around you and try to understand… why.

November 24, 2013

Avoiding Angular's Digest Cycles Limit Reached

Hi guys,
I've recently encountered an issue where in a certain view on an Angular application I've reached the digest cycle limit. If you got here, 80% that you've reached the same issue yourselves.
I would like to elaborate here on how I've managed to avoid it, and fix the issue. It might not work for all the variation of this problem, but it is worth trying before you go into more serious measures.

Avoid calling processing-function from the view
I’m talking about manipulating data from the view in order for it to suite the view needs, e.g. ng-repeat=”value in yourFunction(scopeMemeber)”
If you need to manipulate the data for your view, do it on the logic tier, which is the controller.
Try to use only $scope member directly on the view.

When preparing data on the controller, avoid referencing $scope members up until the very end
If you’re getting a value from some service and on the controller you’re start to “work” on it, try to avoid referencing $scope members in it, since any change to them is a potential dirty-check loop.
What you want to do is try and save the assignment to the $scope member to the very end. Manipulate you’re data using plain JS, and only in the end make the assignment to the $scope member.
Note that sometimes it would even be more efficient to copy an Object, just to make sure it is not linked to the $scope anymore…

Put Sorting, Filtering, etc. outside of the view if possible
Although Angular offers nice ways to sort, order, filtering, etc. as a part of their API on the view level, I would be much better to do that on the logic tier (controller) when the view is complex and have a lot of these.
It is sometimes more efficient to order and array and assign it to the $scope member again, than to do it on the view.

If you have more suggestion, I would be happy to hear about it :)

Cheers