How to set dynamic page titles in Angular 2/4

Standard

I’ve been creating projects using Google’s Angular frameworks for over 3 years now and in that time, I’ve needed to change the document title as the user moved through the app.

In Angular 1.x, I surmounted this challenge by moving my ng-app  declaration to html  tag (instead of the body  tag) and then controlled the page title by using $broadcast and $on  to determine when to change the $rootScope  property that I used to keep track of the page title.

Angular 2/4 has been a different beast entirely and I never gave it (setting dynamic page titles) much thought until I worked on a project that required it. I was fine with having a single page title (usually the application’s name) for the lifetime of the apps I’ve built.

I did a bit of googling and found an article by Todd Moto of the Angular Team that solved the problem in the cleanest way I’ve seen yet.

As I usually do, I’m writing this up here so I don’t go head-scratching at a later date when I need to do this again.

Here’s a link to the Github Gist.

For explanations, please refer to the original post from Todd Moto

 

Handling Web Application Authentication with AngularJS

Standard

Last Friday, I published a post about how I fused the jQuery plugin (Select2) and AngularJS. If you’ve not read it, click here to do so.

Today, I’m inclined to share details of how I conquered (maybe not completely but enough to solve my problems) a problem that confronts most rookie AngularJS developers: HOW TO HANDLE USER AUTHENTICATION. When we build web applications, it’s almost often certain that a form of user authentication would be needed and the traditional model of Web Application design and construction supported this because there was a simple mechanism called “page reloads” which ensures that identities are re-validated and sessions are maintained before or during the service of a request.

Using a client-side technology like AngularJS, this mechanism isn’t built into the library (as at the time of this writing) and so many developers – not unlike myself – wander into this wilderness without a guide. I inquired and scoured the web for many weeks before gaining confidence in the amount of resources that I had in order to make this possible.

Enough of the story now! First thing I realized was that I needed to have a rest API for my AngularJS application to talk with and it was also logical for this API/back-end to handle the authentication of all requests. For my API (and being first a PHP developer before Java, Python, etc), I went with an exciting framework I just discovered about 4 months ago – PhalconPHP. I picked up a GitHub project (Phalcon-Rest) which, by the way, is also pretty exciting in itself.

The Phalcon-Rest README describes the project as follows:

The purpose of this project is to establish a base project with Phalcon that uses the best practices from the Phalcon Framework to implement best practices of API Design.

Writing routes that respond with JSON is easy in any of the major frameworks. What I’ve done here is to go beyond that and extend the framework such that APIs written using this project are pragmatically REST-ish and have convenience methods and patterns implemented that are more than a simple ‘echo json_encode($array);’.

After modifying Phalcon-Rest to be able to competently authenticate requests using a custom HTTP-HEADER set in all requests, I then focused on handling the AngularJS side of things.

First I created an ‘AuthService’ which handles basic user login.

BE WARNED: Most of the code in this post is in CoffeeScript!

December 22 Update: By popular demand, I’ve put up the JavaScript Equivalent for the code in this post on github. Check out the gist here.

At first glance, you’d see a dependency on ‘Session’ and ‘AuthToken’. Basically, Session is a service that I use to (as the name implies) save and retrieve application state on the Client side using HTML5’s SessionStorage so that it’s destroyed when the browser is closed. AuthToken however, I use to save the API request token in localStorage.

The definitions for these Singletons follow:

Obviously this code doesn’t do much by itself. You’d need to create an AngularJS powered login form and attach to it a Controller that depends on AuthService. You can then call the login method once, the form is submitted.

But all of this is just one leg of it all. You still need to check the state of the application for certain routes (when a user navigates to a certain route and maybe reloads the page, how do you handle authentication/identity management then?).

For this, I use ngRoute and in defining my routes, I specify which routes need authentication and which ones do not using the “access” property.

Then in my “run” section, I subscribe to ngRoute’s $routeChangeStart event.

When a request is caught and the user is not authenticated, you can then redirect the user to a login page or if you don’t want them to lose their progress, just show a login modal.

A final step I took was to intercept all $http requests (which were not login requests) and transform the request header to include the API key we now have in localStorage. Here’s the code for my interceptor:

You can then attach this Interceptor to $httpProvider:

That’s it. You should be home and dry now. If you have any questions, please feel free to use the comments section.

I’ve also put all this code into a module and published it as a gist. Click here to view CoffeeScript module.

December 22 Update: JavaScript module now available here.

Using jQuery Select2 and AngularJs

Standard

This past week, I’ve been working on an AngularJS app for the entry and administration of some company data. As dictated by the application’s requirements, users need to be able to make choices from a restricted list of options and so I turned to my trusty “<select>” tag.

I soon noticed though that the options in some part of the application would grow and then make life a bit difficult for the users as they try to choose and this is where the jQuery plugin – Select2 – swooped in to save the day (or so I thought).

As it’s highly discouraged in most quarters to modify the DOM within AngularJS controllers, I needed to wrap my usage of the plugin in an AngularJS directive. Doing this was pretty easy though as I show below using a snippet of my Coffeescript code:

Here’s the gist: https://gist.github.com/ragingprodigy/e775a84c2d47220e1866

I was pretty happy with this because it worked for my simple “select” controls. I was however a bit confused when trying to implement Select2’s remote data feature. Basically, I wanted users to be able to search a remote location and present the results to them using select2.

It would have been easier had I been using plain JavaScript (or so I think) but I wasn’t and I had to figure it out. I then looked at the documentation for Select2 but I hit snags.

Finally, this is the solution that worked for me:

Here’s the gist: https://gist.github.com/ragingprodigy/671142d37a7c588383ba