javascript, Uncategorized

AngularJS Pluralize – build a friendly message, good ui practice

Have you noticed that some web apps creators absolutely ignore common grammar in message or labels?

Well it is common.

You have 1 messages.

Or it might be cooler and human like but still:

You have one messages.


What you’d want to do in your AngularJS application is use a wonderful directive that is baked in and helps you avoid such mishaps.


<ng-pluralize count="report.CriteriaSelected.length"
                 when="{'0': 'No criterion is selected',
                     'one': '1 Criterion is selected',
                     'other': '{} Criteria selected’}"

What this will nicely take care for you are the conditions when Nothing is selected or you have 1 or many conditions where a different text is used.

Thereby avoiding using “message(s)”.


Going further, i would suggest using internationalization i18n for your labels in such cases so that it makes sense in other languages.


This feature exists for a while now.



Share This:


AngularJS – being aware of environment


Single Page Apps can be awesome

Single Page app is not a myth, its real and its awesome.

But strong , fast tools are definitely something a developer should always use. Grunt and Gulp are extremely useful for running tasks that optimize web resources, run automatic tests , monitor changes and refresh your browser as you tinker with the next big thing but also run any custom task you desire.

I had a challenge with an AngularJS app that was strictly using an API from a another domain and we had several environments (local, stage, prod – typical right? ) . Clearly those environment use different settings, and have different urls.

AngularJS provides nice ways of settings variables available across your app through injection.

Here is an example that creates a module ‘app.config’ (or appname of your choice) and sets constant (using this string you can inject and use it)

Define constants within AngularJS app

angular.module("app.config", [])

.constant("ENV", {
  "name": "development",
  "apiEndpoint": "http://localhost:5000",
  "basePath": ""


Inject and use variables within the app (CoffeeScript)


angular.module('app.controllers', ['restangular', 'app.config'])
.config (RestangularProvider, ENV)->

At this point i can inject and use ENV throughout controllers and as you can see above in config state of initializing an Angular app. Since i’m using Restangular to interact with an API i needed to set a base url.

What happens on automated deployments? Solution

I’ve had a chance to use codeship and jenkins for building codebase and running tests, etc. Deploying to Staging or production would require that you replace config module with variables dependent on the environment. You don’t have to do anything manually. Here is the solution if you’re using Grunt.

NPM you need to install:


This is your (just a portion that is of interest, loading and using ng-constant) :



ngconstantConfig = 
      # Options for all targets
        space: "  "
        wrap: ""use strict";nn {%= __ngModule %}"
        name: "app.config"

      # Environment targets
          dest: "<%= %>/scripts/shared/config.js"

            name: "development"
            apiEndpoint: "http://localhost:5000"

          dest: "<%= %>/scripts/shared/config.js"

            name: "stage"
            apiEndpoint: ""

Set configuration for grunt :

     ngconstant: ngconstantConfig

In regular JavaScript this is simply :


grunt.initConfig({ ngconstant: ngconstantConfig });


One more simple step (setting up the task)

env = process.env.NODE_ENV || 'development'

grunt.registerTask "build", ["clean:dist","ngconstant:"+env, "copy:ngconfig"...

This will register a task in a development environment “ngconstant:development” which will trigger NPM grunt-ng-constant to generate a file config.js that would include all the variables you defined in ngconstantConfig object for a specific environment.


Possible issue and solution

At least in my project (coffeescript) config.js was generated but too late and wasn’t picked up by other task that packaged everything into one file. My solution was to write a small task named “copy:ngconfig” that simply copied the generated file explicitly

This is simply copying config.js into Temporary location which then available for other task to package.

                files: [ 
                    src: ["<%= %>/scripts/shared/config.js"]
                    dest: ".tmp/scripts/shared/config.js"


Voila , your application will environment specific values on any environment

Next time your code is pulled into stage or production , it can run> grunt build   and code will be optimized, packaged into “dist” folder and deployed to optimally Amazon CDN


Share This: