Oskar4j 2014-11-12 at 22.00.25

Angular – Bootstrap – Jade – Stylus – CoffeeScript boilerplate webapp with Yeoman

Sorry about all the buzzwords in the title but it really describes what this note-to-self post is about.
How to create a boilerplate web app using AngularJS as framework, Bootstrap as HTML/CSS base, Jade as HTML replacement, Stylus as CSS replacement, and CoffeeScript as a Javascript replacement/generator/transpiler. All using Grunt as the glue that keeps everything together.
Npm and Bower makes sure all dependencies are in place. And Karma for the testing.

To create the scaffolding I use a tool named Yeoman that has all these generators that installs all tolls you need, configures Grunt, npm and Bower and generates a basic app file structure so you can jump straight into the code.

Lots of tools and replacements/generators/transpiler languages and there certainly are better or faster ones out there, but these makes me comfortable and I can get to work in 2 min.

Anyway, this is how I do it:

npm install --global yo bower grunt-cli
npm install --global generator-angular-jade-stylus

mkdir newapp && cd $_
yo angular-jade-stylus --coffee --jade --stylus newapp

Run npm cache clean and repeat the last line if it fails.
Answer yes to all questions.

Run grunt serve and point your browser to localhost:9000 unless it does so for you.

Bam, done.
Thank you Yeoman.

Again: Add Authorization header to AngularJS $http

In my last post I showed how I add an Authorisation header to outgoing $http calls in AngularJS. I’ve changed the way I do it, this which I think is easier to read.

angular.module('app')
  .factory('RequestInterceptor', [
    'AuthDataService'
    (AuthDataService) ->
      interceptor = 
        request: (config) ->
          header = AuthDataService.getAuthData()
          if header then config.headers['Authorization'] = "Basic #{header}"
          config
      interceptor
])

angular.module('app').config(['$httpProvider', ($httpProvider) ->
  $httpProvider.interceptors.push 'RequestInterceptor'
])

The AuthDataService is the same as in my last post, but without the the setting of $http.defaults.headers.common['Authorization'].

Oskar4j 2014-09-11 kl. 07.53.15

Add Authorization header to AngularJS $http

I recently had to add an Authorization header to all $http requests in an AngularJS app.
Here’s how I did it in Coffeescript.

#AuthData.coffee

angular.module('app')
.factory 'AuthDataService', [
  'localStorageService'
  '$base64'
  '$http'
  (localStorageService, $base64, $http) ->
    current_auth_data = localStorageService.get('authorization_token')
    if current_auth_data
      $http.defaults.headers.common['Authorization'] = "Basic #{current_auth_data}"

    return {
      setAuthData: (authdata) ->
        return unless authdata
        encoded = $base64.encode(authdata)
        localStorageService.set('authorization_token', encoded)
        $http.defaults.headers.common['Authorization'] = "Basic #{encoded}"
      clearAuthData: ->
        localStorageService.remove('authorization_token')
        $http.defaults.headers.common['Authorization'] = ''
      getAuthData: ->
        return localStorageService.get('authorization_token')
    }
]

Upon initialization it checks if there’s a authorization_token saved in your local storage. If there is, set it as a Authorization header on $http.
Whenever you set or clear the auth data, the header for $http changes as well.

EDIT: I’ve written another post about how to add Authorization header to AngularJS $http

Oskar4j 2014-09-23 kl. 22.02.20

Create a nested array recursively in CoffeeScript

In an old post called Create a nested array recursively in Javascript I wrote how to go from

[
    {id: 1, title: 'hello', parent: 0},
    {id: 2, title: 'hello', parent: 0},
    {id: 3, title: 'hello', parent: 1},
    {id: 4, title: 'hello', parent: 3},
    {id: 5, title: 'hello', parent: 4},
    {id: 6, title: 'hello', parent: 4},
    {id: 7, title: 'hello', parent: 3},
    {id: 8, title: 'hello', parent: 2}
]

Read more…

Oskar4j 2014-09-11 kl. 07.53.15

AngularJS: $watch and $timeout

As you might know, AngularJS has an event loop, called $digest, that checks and updates all bindings and values.
You can have a DOM element only show when a scope variable has a certain value, like this:

<div ng-show="show_div">Text in div</div>

Whenever the $digest runs, it checks if $scope.show_div is true and if it is, the div is shown. If not true, the div is hidden.

That means that in your controller you can toggle the visibility of the div by simply setting $scope.show_div = true/false. However, if you do this on mouseover an element or change the value very frequently some other way the $digest might not have had the time to finish it’s loop and the div won’t toggle as it should.

That’s where $timeout comes in. It’s a wrapper for javascript’s setTimeout with the addition that it triggers a $digest loop at the end meaning that anything you changed will be updated as it should.
So instead of $scope.show_div = true and then $scope.show_div = false you do:

$timeout(function() { $scope.show_div = true; }, 0);
//and
$timeout(function() { $scope.show_div = false; }, 0);