angular js - ngCookie
Warning: if you need to set cookie expiration, httpSecure, path or subdomain then ngCookies doesn't support as of v1.2.7. I plan to use jquery-cookie.js which angular issues also reference, and there is a number of issues open related to this gap in $cookies.
Angular js provides support for cookie manipulation in the core library file angular-cookies.js (v1.2.7). That file defines a module ngCookies with 2 factory services:
- $cookies
- $cookieStore
For setting of a simple property on a cookie then $cookies is the factory to use.
For setting js objects (key-value pairs) in the cookie then $cookieStore is what to use.
To use:
1. include the angular-cookies.js file in yout html
2. include the module ngCookies as a module dependency where you wish to use
3. request $cookies or $cookieStore (or both) to be injected by the dependency injector
Using $cookie.
With $cookie you can treat a cookie name as a property on $cookie.
var cookieValue = $cookies.cookieName; // get value from cookie of cookieName
$cookies.cookieName = "test1"; // set "test1" into cookieName:
Setting a cookieName value to undefined will result in the cookie being deleted.
Warning: it appears only strings are supported as cookieValues.
Big Flaw
You can't set the expiration date on a cookie using $cookie! Cookie Expires gets defaulted to "Session" which means its destroyed when the browser is closed.
You can't set the path either or httpOnly or sub domain.
Setting an expiration when creating client side cookies is common. That an expiration is not possible to set when set cookie value severely limits ngCookies usefulness.
It basically means its really only useful for reading cookies set server side and session cookies. WTF?
This should come with a big warning in angular docs.
Unit testing
In your unit tests you can check that a cookie value is set or not by checking for the value in cookieName.
Under the covers
Angular $cookies has the latest cookie values in $cookie. To accomplish that angular sets up a poller which ensures that $cookie has the up to date cookie values
Angular $cookies also sets up a watch to run at the end of each eval. This compares whats in current cookies to what the values were after last update and persists any changes.
ngCookies uses angular $browser, a private service, to setup polling and to save/retrieve cookies. I'd note that $browser does a lot more besides.
It concerns me how $cookies work under the covers:
1. angular $cookies runs a poll to execute every 100ms to check and keep the in memory value of the cookie in synch with browser cookie changes
2 angular js $cookies also sets up a watch to run at the end of each eval to save any cookie changes to browser cookie
Both have checks to minimize code run, but still both run very frequently
Ok, not a big overhead, but is that really necessary?
Could a lazy loading strategy be more efficient? Or at least make it configurable, not every app will care to support catching cookie updates from elsewhere.
Angular js provides support for cookie manipulation in the core library file angular-cookies.js (v1.2.7). That file defines a module ngCookies with 2 factory services:
- $cookies
- $cookieStore
For setting of a simple property on a cookie then $cookies is the factory to use.
For setting js objects (key-value pairs) in the cookie then $cookieStore is what to use.
To use:
1. include the angular-cookies.js file in yout html
2. include the module ngCookies as a module dependency where you wish to use
3. request $cookies or $cookieStore (or both) to be injected by the dependency injector
Using $cookie.
With $cookie you can treat a cookie name as a property on $cookie.
var cookieValue = $cookies.cookieName; // get value from cookie of cookieName
$cookies.cookieName = "test1"; // set "test1" into cookieName:
Setting a cookieName value to undefined will result in the cookie being deleted.
Warning: it appears only strings are supported as cookieValues.
Big Flaw
You can't set the expiration date on a cookie using $cookie! Cookie Expires gets defaulted to "Session" which means its destroyed when the browser is closed.
You can't set the path either or httpOnly or sub domain.
Setting an expiration when creating client side cookies is common. That an expiration is not possible to set when set cookie value severely limits ngCookies usefulness.
It basically means its really only useful for reading cookies set server side and session cookies. WTF?
This should come with a big warning in angular docs.
Unit testing
In your unit tests you can check that a cookie value is set or not by checking for the value in cookieName.
Under the covers
Angular $cookies has the latest cookie values in $cookie. To accomplish that angular sets up a poller which ensures that $cookie has the up to date cookie values
Angular $cookies also sets up a watch to run at the end of each eval. This compares whats in current cookies to what the values were after last update and persists any changes.
ngCookies uses angular $browser, a private service, to setup polling and to save/retrieve cookies. I'd note that $browser does a lot more besides.
It concerns me how $cookies work under the covers:
1. angular $cookies runs a poll to execute every 100ms to check and keep the in memory value of the cookie in synch with browser cookie changes
2 angular js $cookies also sets up a watch to run at the end of each eval to save any cookie changes to browser cookie
Both have checks to minimize code run, but still both run very frequently
Ok, not a big overhead, but is that really necessary?
Could a lazy loading strategy be more efficient? Or at least make it configurable, not every app will care to support catching cookie updates from elsewhere.
Do you have any updates on when ngCookies will support expiration date?
ReplyDeleteThere are issues open e.g. https://github.com/angular/angular.js/issues/950
Delete...but I don't believe there is any support yet in angularjs cookies