Protractor/Jasmine bug in Angular:
Fix by using: expect<any>
When adding routing to an AngularCLI project you need to also update the startup test with the RouterTestingModule.
Failure to do so results in the following error when running ng test:
Here is the fix (click on the image to enlarge):
Source code available here:
https://github.com/stevenh77/angular-lob-app/commit/f582ecf5034af3222a686ae0e9f237f6528aefa6
As of 3rd April 2017, here is a simple example of how to add routing an AngularCLI project.
All the source code and changes to the AngularCLI project can be found here:
https://github.com/stevenh77/angular-lob-app/commit/30a6a60c0f5b195d5edb290e8f3df902ec605ccf
Step 1: Create two new files in your app folder for basic components which will display the views we would like to route between. I’ve called mine Home and Away.
Step 2: Edit the app.component.html in your app folder to contain the router-outlet.
Step 3: Create an ‘app.routes.ts’ file in your app folder. This example defaults to displaying the HomeComponent and displays the AwayComponent for path “away”.
Step 4: Update the ‘app.module.ts’ file. This is the most complicated step. I’ve shown the before and after files in the screenshot below (click image to enlarge):
Why all the changes to app.module.ts and what do they do?
Lines 5, 29, and 30: In order for us to log the routes to the console on start up which is good for debugging, you need to import the Router module (line 5). This gives us the ability to inject the router object into the constructor (line 29). Line 30 logs the router to the console on app start up.
Lines 8, 9, 15 and 16: Lets our app know about our new Home and Away components.
Lines 10, 22 and 24: Lets our app know about our new router and it’s configuration.
Here is our app running. Note I also have Augury installed which is an Angular debugging tool which can help debug your Angular app including your Router.
Add a simple “.appveyor.yml” file to the root of your project:
Next sign in to https://ci.appveyor.com and mark your repo as an AppVeyor project.
Once you’ve added your project you can build your project within AppVeyor. A build will also get kicked off with every new commit/push to your repo:
Add the following code to you readme.md file in GitHub to get a CI build badge.
npm install --save-dev karma-phantomjs-launcher
Then update karma.config.js (lines 11 and 31):
You’ll now get the following error if you attempt to npm test or ng test:
To fix this just uncomment the following lines from your polyfill.ts:
You can use the same approach for Express, body-parser, cors, morgan, etc.
The typings file are stored under the folder node_modules/@types
Auth0 is great for integrating security into your applications.
In this blog we’ll look at how simple it is to setup Auth0 and then create an Angular app that uses it.
1) Go to Auth0.com and setup your account:
2) Now we’ve got our Auth0 account we can setup our ASPNetCore WebAPI:
You can then download or fork the startup project.
Finally, let’s setup our Angular2 app:
Then download or Fork on GitHub (I’m forking on GitHub)
If either fail to download or fork you can manually download from here:
https://github.com/auth0-samples/auth0-aspnetcore-webapi-sample
https://github.com/auth0-samples/auth0-angularjs2-systemjs-sample
Here’s a simple example how to create your own hyperlink directive, demonstrating changing the DOM with directives.
Usage:
Here's another example this time using an explicit call of the transclude function:Here I’ve kept the hyperlink element in the DOM as this is considered a best practise by the Angular team since v1.3.
Taken from this style guide: http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/
After creating services, we will likely inject them into a controller, call them and bind any new data that comes in. This becomes problematic of keeping controllers tidy and resolving the right data.
Thankfully, using angular-route.js
(or a third party such as ui-router.js
) we can use a resolve
property to resolve the next view's promises before the page is served to us. This means our controllers are instantiated when all data is available, which means zero function calls.
function MainCtrl (SomeService) {
var self = this;
// unresolved
self.something;
// resolved asynchronously
SomeService.doSomething().then(function (response) {
self.something = response;
});
}
angular
.module('app')
.controller('MainCtrl', MainCtrl);
function config ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
resolve: {
doSomething: function (SomeService) {
return SomeService.doSomething();
}
}
});
}
angular
.module('app')
.config(config);
At this point, our service will internally bind the response of the promise to another Object which we can reference in our "deferred-instantiated" controller:
function MainCtrl (SomeService) {
// resolved!
this.something = SomeService.something;
}
angular
.module('app')
.controller('MainCtrl', MainCtrl);
We can go one better, however and create a resolve
property on our own Controllers to couple the resolves with the Controllers and avoid logic in the router.
// config with resolve pointing to relevant controller
function config ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
controllerAs: 'main',
resolve: MainCtrl.resolve
});
}
// controller as usual
function MainCtrl (SomeService) {
// resolved!
this.something = SomeService.something;
}
// create the resolved property
MainCtrl.resolve = {
doSomething: function (SomeService) {
return SomeService.doSomething();
}
};
angular
.module('app')
.controller('MainCtrl', MainCtrl)
.config(config);
While the routes are being resolved we want to show the user something to indicate progress. Angular will fire the $routeChangeStart
event as we navigate away from the page, which we can show some form of loading and ajax spinner, which can then be removed on the $routeChangeSuccess
event (see docs).
Quick list of conferences to keep an eye open for:
http://ng-conf.org/ | Angular / Google | March | YouTube |
http://ngeurope.org/ | Angular / Google | October | YouTube |
http://jsconf.com/ | JavaScript | Monthly | YouTube |
http://www.dotjs.eu/ | JavaScript | November | YouTube |
http://jqueryuk.com/2015/ | jQuery | March | Vimeo |
javascript-summit | JS / jQuery | November | |
http://conf.reactjs.com/ | React / Facebook | January | |
http://www.buildwindows.com/ | Microsoft | April | Channel9 |
https://anglebrackets.org/ | Microsoft | May | |
http://reactconf.com/ | Reactive Systems | April and Nov | |
https://www.google.com/events/io | June | YouTube | |
https://developer.apple.com/wwdc/ | Apple | June | Apple |
https://fbf8.com/ | April | Facebook Live |
Here’s an example of a simple rest application, written to demonstrate simple techniques to get people started with Angular:
Source: https://github.com/stevenh77/ng-simple-rest-app
Client features
- default page not being shown by the router
- automatic conversion of Json strings into JavaScript dates (generic/aop approach)
- date control bound to model object from a data service
- select control databound to model from a data service
- confirmation dialog
- rest service calls for get, post, put, delete
- bootstrap layout for form
- form validation
- app navigation from controller using location and window services
- logging abstraction
- promises for service calls including error handling
- generic application level error handling
- busy indicator
- unit tests with mocks and promises
- material design for form entry
Server features:
- simple rest endpoints
- compression
- request logging to console
- CORS enabled
- object retrieved from JS array based on key
- object removed from JS array based on key
The following explanations were taking from various Angular docs, Misko code examples and StackOverflow posts.
Factory and Service are the most commonly used recipes. The only difference between them is that Service recipe works better for objects of custom type, while Factory can produce JavaScript primitives and functions.
Factories are an example of the revealing module pattern.
Providers have the advantage that they can be configured during module configuration phase.
Services, Factories as well as Values are all created under the hood using Providers.
Basic change detection scope and directives implemented in one page of code, basically it’s Angular without Angular!
Video: https://www.youtube.com/watch?v=Mk2WwSxK218
Demo: http://stevenhollidge.com/blog-source-code/angular-from-scratch
Code:
You can have your routing code make services or data available to your controller by using resolve.
This is how we expose these functions to the controller:
An Angular list that features bootstrap layout, reads and denormalises JSON data from a text file and has filtering.
Screenshot:
I have added a nice fade animation to each step of the wizard I created in my previous blog post.
Watch the video below or try out the live demo:
It turned out to be very simple indeed:
1) Add a script reference to the Angular-Animate.js library in your html page
2) Create an Animate.css file which will contain your animation details and add a reference within your html page. I’ll explain the content of this code in a second.
3) Add a css class to the area you are animating, this is so your css code can locate it. I added “fade-animation” class to each of the three wizard steps.
4) Finally add a reference to ngAnimate for Angular
And that’s it. Right, now for the trickiest part, here is the animate.css code:
.fade-animation.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
display:block!important;
}
.fade-animation.ng-hide-add.ng-hide-add-active,
.fade-animation.ng-hide-remove {
opacity:0;
}
.fade-animation.ng-hide-add,
.fade-animation.ng-hide-remove.ng-hide-remove-active {
opacity:1;
}
When you break this down there’s not much to it. The first section is saying I want the animation to take half a second, in all the various browsers. The display:block!important line is telling angular to override it’s default for hiding.
The other two css setters simply show and hide. Now the interesting bit is the css selectors. You’ll recognise the fade-animation selector as our class we are using for identification purposes.
All the ng-hide-* css classes are what Angular adds as it cycles through its event lifecycle for showing and hiding.
This would be the lifecycle for moving for the user moving from Step One to Step Two: