Posts

Angularjs style guide adoption - John Papas

As a team we adopted John Papas Angularjs style guide at the end of 2014. The Anguarjs communities understanding of best practices for Angularjs use has come a long way is a short time. I can say now having adopted and used it that John Papas style guide is a good step forward. We've been developing with Angularjs since 2013 and over that time our Angularjs code base looks quite different style wise. It looks like it was written by many (talented) individuals for various reasons such as our use of best practices evolved. Ideally the codebase should look as if written by one person: easy to learn and understand other peoples code. So as a team we wanted to write better Angularjs code. We are also looking ahead to Angular 2.0. There are significant changes in that release and where possible we'd like to write code now that will make it easier to adopt Angular 2.0 in future. As a team we investigated various angularjs coding standards/style guides such as googles, codeless, ...

Keep karma test data DRY

We used to include mock test data with our Karma test code. When you build up a large body of complex tests the test data setup can run to hundreds of lines. It can be hard to read and understand. Oftentimes the same data is needed across many unit test suites and is repeated. Our solution is to create a /mock-data folder and put into it js files with mock json data for common json objects used by our unit tests e.g. customer object. When we call an expectGET() then we return a copy of the mock data e.g.  $httpBackend.expectGET('/api/...../').respond(angular.copy(CUSTOMER_MOCK_DATA)); If you build your mock test data well you can cover multiple tests with one mock data definition. For test cases that need unique combinations I find that I just copy the mock data object and then tweak select properties as necessary in the test or within a block of tests. e.g.  var myDeCustomer = angular.copy(CUSTOMER_MOCK_DATA);         myDeCustomer.profile.locale...

Angularjs expression size and watches

In Angular you can explicitly register a watch and a callback to be called when it changes   e.g.      $scope.$watch(expression, callback) ..or implicitly using a binding expression  e.g.     {{userName}} Angular keeps track of all watches on scope so that it can detect when changes have occurred and thus update the DOM or call a watch callback. Angulars code to detect changes by evaluating all the watches is called the "digest loop". The digest loop stores the value of the watch expression evaluation and when next the cycle runs it compares the old value to newly computed expression value. If there are differences then it will eventually intelligently update the dom and/or call impacted watch callbacks (once all changes have been resolved) The awesome book "Mastering Web Application Development with AngularJS" explains this well in Chapter 11. Chapter 11 includes a section on performance tuning. One advice is to "Consider the size of expre...

Thumbs up for Angular 2.0

wow! Big changes: ng-controllers - gone, $scope - gone, directives - gone, modules- gone, new language AtScript added... wow! Still learning about Angular 2.0. But honestly as I think about it, I like what I see so far in Angular 2.0: I like the new Directive syntax, write as a class and annotate; well ok by me, I mean, lets face it Directives in 1.x are ugly changing to use ES6 modules very logical and makes sense (Embers doing same) eliminating $scope is a good idea, I always felt its like a global space and way too easy to abuse, $scope use is already being minimized in latest best practices...so its on the way out already controllers are written as classes and annotated; not clear to me how to completely eliminate ng-controller, but I don't see controllers going away but rather how controllers are activated on a page is changing changes to html syntax look a little weird but I'm sure we'll learn that quickly AtScript adds some useful looking beh...

angularjs and karma performance memory problems

Give me the answer now : switch Karma to run Firefox not Chrome More details Our team is building a pretty complex angularjs app. We write unit tests and run them using Karma. The unit tests are run on a file change watch and just run in the background. We have almost 2000 unit tests. Its all been working great until recently when the test run gets much slower after each run. Its now at a point that by the 3rd karma run, karma grounds to a halt i.e. 1 run 15 secs, 2nd run 30 secs, 3rd run 1min + I should not the app itself is not exhibiting significant memory issues (although profiling and tuning is needed) just the unit tests. Step 1 - find out whats happening with our Karma tests? Using google Chrome Task Manager, monitor the Karma browser tab. The monitor shows us memory and cpu (you can also right click and add more columns). This is a rough measure but we could see karma tab: - memory almost doubled each run 300mb, 600mb, 800mb. - cpu was maxing out after 3rd run S...

jasmine spy access individual arguments passed to spy

Jasmine spies are super useful when writing unit tests You can check arguments passed to a spy x with:  expect(x).toHaveBeenCalledWith(arguments) toHaveBeenCalledWith() expects a match on all arguments But what if you don't know all the arguments e.g. only sure of the 1st but not the rest? There is a way,  heres the fiddle and code below: describe("Spy argumnts access", function() {   it("should access 1st argument to spy", function() {     var mockCallback = jasmine.createSpy("mockCallback");         mockCallback("denis", 22, {unknown: 1})       expect(mockCallback).toHaveBeenCalled();       expect(mockCallback.argsForCall[0][0]).toBe("denis");       }); }); FYI Add Jasmine as an external library, I found this on other examples: http://searls.github.io/jasmine-all/jasmine-all-min.js

angularjs select: watch the ng-model versus use ng-change

Been wondering about the best approach when using angulars select. You pass it an ng-model to hold the currently selected choice (including initialization). Angular provides at least 2 options for being notified of changes in the dropdown: 1. use ng-change on the select and have it call a method on scope to handle the change 2. watch the ng-model and when it changes then handle the change So which is better? A typical mvc approach is to listen to the model and respond to changes. Angular allows us to watch the model and do same. For watch read listen. One downside of watching the selects ngModel is that watch fires a lot. You do get new and prev values passed in the watch so you could compare both and do nothing if same and thus save some cycles. Using ng-change is simpler, it only fires when the drop down changes. You can see whats happening by looking at the html (although it should not be so difficult to understand by looking at the watch code either) I prefer #2 wat...