DDD: Utilizing JavaScript for Aggregate Root Encapsulation

Struggling to find a straightforward example of implementing an Aggregate Root (DDD) while properly encapsulating its internal state using JavaScript/TypeScript? Below, I propose a solution and welcome any suggestions for improvement:

import cloneDeep from 'clone-deep';
import { deepFreeze } from '../utils'; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

export class AggregateRoot<TEntityProps> {
  // TODO EntityId
  
  protected readonly props: TEntityProps

  constructor(props: TEntityProps) {
    /** Encapsulate aggregate's state from the outside world */
    this.props = cloneDeep<TEntityProps>(props)
  }
  
  /** Extract the state from an aggregate. 
   * 
   * Aggregate becomes unchangeable (read-only) after calling the flush method.
   * */
  public flush(): TEntityProps {
    return deepFreeze(this.props)
  }
}

// Example of usage with User entity
export class User extends AggregateRoot<UserProps> {
  constructor(props: UserProps) {
    super(props)
    
    // Perform props validation here

  }

  get firstName() {
    return this.props.firstName
  }

  get lastName() {
    return this.props.lastName
  }

  get updatedAt() {
    return this.props.updatedAt
  }
}

Answer №1

Here's an alternative approach for you to consider:

  public clear(): TEntityProps {
    return deepFreeze(this.props)
  }

Alternatively, you could use:

  public backup(): TEntityProps {
    return cloneDeep(this.props)
  }

It's important to note that by using this method, memory usage will double. Therefore, it may be more suitable for smaller data sets.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for successfully transferring an image through an XMLHttpRequest

I found this helpful resource at: I decided to test out the second block of code. When I made changes in the handleForm function, it looked like this: function handleForm(e) { e.preventDefault(); var data = new FormData(); f ...

Issues with Bootstrap sidebar and footer functionality

I need to implement a consistent footer on multiple web pages created with jQuery and bootstrap 3. Following the example provided by Bootstrap, I have written the script below to add the footer: // Default $( document ).ready(function() { $(' ...

Retrieving information from an openDatabase using AngularJS

Encountering an issue while trying to retrieve data from openDatabase and display it in a listview. Following advice from a thread, I added $scope.$apply(); after $scope.items = $data;, but this resulted in an error: [$rootScope:inprog] $apply already in p ...

Is there a way to set up TS so that it doesn't transpile when an error occurs?

Is there a way to configure my tsconfig.json file in order to prevent transpiling if an error occurs? I have searched the documentation but couldn't find any flag or configuration for this. Does anyone know how I can achieve this? ...

How can I achieve a pixelated texture effect using three.js?

I revamped a demo similar to Minecraft where you can jump and build blocks. However, the texture of the blocks I create appears smooth instead of pixelated, and I'm not sure why. Here is the relevant source code snippet: var textureDirt = THREE.Imag ...

It seems that every time you save data in Angular, the local storage array gets overwritten

While using Angular, I encountered an issue with saving to local storage. The code works fine for saving items initially, but on refreshing the page and trying to add more objects to the local storage array, it overwrites instead of appending. Can you help ...

Choose an alternative following the start-up phase

I have been searching for solutions on various platforms, including Stack Overflow, but nothing seems to work for me. I am struggling with selecting the first option after initializing the box because currently it is choosing a blank option that is not eve ...

Angular routing with Javascript functionality

I have created a simple Angular Router, but I am facing an issue where the JavaScript is not executing or I am unable to access elements inside the templateUrl. I mostly followed the code from this tutorial, here. Below is my index file: <html ng-app= ...

The error message "Equals is not defined: Selenium IDE Custom Format" indicates that the function "

I've been working on enhancing the functionality of the selenium IDE through custom functions. I successfully added my custom functions to user-extensions.js and they work as expected within the IDE. However, I encountered issues when trying to export ...

Determine in Node.js whether a variable is present in the request object for each page the user visits

Currently, my authentication system utilizes passportjs to define req.user when the user is logged in. As my website expands beyond its current 5 pages, I have been checking for the existence of req.user at the top of each route. Based on whether it exist ...

Issues with React TypeScript type definitions not functioning as expected

When I installed typings, I encountered this error in the terminal: Error Message in Terminal Error TS2320: Interface 'Element' cannot extend types 'ReactElement<any>' and 'ReactElement<any>'. The named property ...

How can we optimize the category system for our carousel display?

I discovered the amazing combination of using lightGallery along with the cycle2 plugin. My images are categorized, and I would like them to dynamically change when a category is clicked. Can anyone provide an example on how to achieve this? The categorie ...

Node.js used to create animated gif with unique background image

As I navigate my way through the world of node.js and tools like express and canvas, I acknowledge that there might be errors in my code and it may take me some time to grasp certain concepts or solutions. My current project involves customizing a variati ...

AngularJS - Swipe to update

I've been trying to use the pull to refresh plugin for Angular JS, but unfortunately it's not working for me. Even though I can see the text, when I try to pull nothing happens! I followed all the steps outlined on this GitHub page: https://githu ...

Showing and hiding div elements

I am looking to enhance this toggle function by making the div content retract and hide when the same link is clicked again. Additionally, I would like it to retract completely when a different link is clicked before the associated content slides down. Fu ...

Angular update component

In a scenario where data is being sent from two different components - let's call them OneComponent and TwoComponent. These components send their data to a <code>ResultComponent through the Input() decorator. Within the ResultComponent, the rece ...

Troubleshooting: Why Your Angular Data Binding is Failing

I am integrating a WCF REST service with an AngularJS application. My goal is to retrieve account information based on the account number provided, however, I am encountering an issue where the text "Account_Type" is displayed three times before showing th ...

Using Typescript mapped types to pair enum values as keys with corresponding values from an interface

My preferences are represented as an enum of strings: export enum PreferenceTypes { language = "language", unit = "unit", } To define the structure of an expected object, I can create an interface where the keys correspond to t ...

Using JavaScript, transform a client's date/time string into a JSON-compatible date/time string

I need to find a way to convert a client's date/time string on a form into a JSON date/time string using JavaScript with moment.js for a Django REST API backend service. Here is the initial attempt: document.getElementById("dt_tm").value = moment(do ...

How to use jQuery to trigger multiple divs having the same class

Using the Cycle 2 plugin, I have this code snippet currently: jQuery(function($){ $('.cycle-slideshow').cycle('pause'); $('.cycle-slideshow').hover(function () { //mouse enter - Resume the slideshow $('.cycle-sli ...