How to store user information between sessions in a Cookie in Angular

Updated: 2023-04-28

How to store user's information and choices between browser sessions

A common problem in enterprise applications is to store some information and choices of the User between browser sessions (a.k.a. working days) without storing the information in a Database.

This solution is thought for Intranet enterprise solutions and not recommended for public application on the web for privacy reasons.

Typical usages of this solution are:

  • store the color palette
  • remember the last page / tab / record visited

If the user delete the cookie or use a different device to access the web application the last data in not shown. If the device change frequently, a persistent solution like a database is definitely better.

Angular Service code

This Angular Service class handles allows to record new parameters in the cookie of the browser.

The most relevant part of code is :

document.cookie = `${parameter}=${value}; ${this.expirationDate}; ${this.domain}`; 
  } 

This code write the cookie parameter in the browser, you can find the documentation on mdn web docs

To avoid that the information is stored only on the page in which the user is navigating at the moment of the call of the function, the doman has to be specified in the cookie or the value will be linked to the document / page.

According to the mdn web docs:

;domain=domain (e.g., 'example.com' or 'subdomain.example.com'): The host to which the cookie will be sent. If not specified, this defaults to the host portion of the current document location.

Here you have the complete code:

import { Injectable } from '@angular/core'; 
 
@Injectable({ 
  providedIn: 'root' 
}) 
export class CookieService { 
  private parameterMap: { [name: string]: string } = {}; 
  private readonly expirationDate: string 
 
  // we save the domain to avoid that for every path a different cookie is used 
  private readonly domain: string; 
 
  constructor() { 
    this.expirationDate = this.getCookieExpiration(); 
    this.domain = this.getDomain(); 
 
    if (document.cookie) { 
      const paramList = document.cookie.split(';'); 
      paramList.forEach( 
        parameter => { 
          const values = parameter.trim().split('='); 
          this.addToCookieWithName(values[0].trim(), values[1].trim()); // there is no reverse conversion for enum 
        } 
      ); 
    } 
  } 
 
  addToCookieWithName(parameter: string, value: string): void { 
    this.parameterMap[parameter] = value; 
  } 
 
  addToCookie(parameter: CookieType, value: string): void { 
    this.parameterMap[parameter] = value; 
    document.cookie = `${parameter}=${value}; ${this.expirationDate}; ${this.domain}`; 
  } 
 
  getValue(parameter: CookieType): string | null { 
    if (this.parameterMap.hasOwnProperty(parameter)) { 
      return this.parameterMap[parameter]; 
    } 
 
    return null; 
  } 
 
  removeFromCookie(parameter: CookieType): void { 
    this.parameterMap[parameter] = ''; 
  } 
 
  refreshCookie(): void { 
    let cookieString = ''; 
    Object.keys(this.parameterMap).forEach( 
      field => { 
        if (this.parameterMap[field]) { 
          cookieString += (field + '=' + this.parameterMap[field] + ';') 
        } 
      } 
    ); 
    document.cookie = cookieString + this.expirationDate; 
  } 
 
  getCookieExpiration(): string { 
    const d = new Date(); 
    d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000)); 
    return 'expires=' + d.toUTCString(); 
  } 
 
  getDomain(): string { 
    const domainName = (window as any).location.hostname; 
    return 'path=' + domainName; 
  } 
} 
 
export enum CookieType {theme = 'theme'} 

In this example we define a CookieType theme because we want to let the user to choose the Angular material theme from a predefined list.

We can read the value from the cookie in our app.component.ts:

ngOnInit(): void { 
	const initialTheme = this.cookieService.getValue(CookieType.theme); 
 
 if (initialTheme) { 
  this.themeService.setTheme(initialTheme ) 
} 
} 

With this code we read the value in the document of the browser, if the theme is found we set it in the theme service.

To monitor the user and set/change the theme when he update it in the screen we use an Observable:

this.themeService.theme$ 
  .pipe( 
		map(theme: string => this.cookieService.addToCookie(CookieType.theme, theme)), 
takeUntil(this.destroy$)).subscribe() 
} 

In other use cases you can apply the same logic, using an observable and updateing the cookie from the service. This will allow the user to change his/her parameters from every page in the application.


You could be interested in

Right click context menu with Angular

Right click custom menu inside dynamic lists with Angular Material
2020-05-31

Enums in Angular templates

How to use enum in the html template
2019-01-21
WebApp built by Marco using SpringBoot 3.2.4 and Java 21, in a Server in Switzerland