Mastering the art of crafting an Angular Domain Model accurately

When creating a domain model, is it best to define and set the properties inside the constructor for efficiency?

In my attempt below, I have defined the properties outside the constructor. Should I be setting them only inside the constructor to reduce the amount of code?

Here is what I believe to be the correct way:

export class TestModel1 {
  public currentPage: number = 0;
  public hasNext: boolean = false;
  public hasPrev: boolean = false;
  public pageSize: number = 0;
  public totalItems: number = 0;

  constructor(data: any) {
      this.currentPage = data.currentPage;
      this.hasNext = data.hasNext;
      this.hasPrev = data.hasPrev;
      this.pageSize = data.pageSize;
      this.totalItems = data.totalItems;
  }
}

Although functional, this implementation appears lengthy with a lot of lines of code.

Currently, I pass in a data object and then map the values. Is there a more efficient way to achieve this using the constructor function?

Answer №1

When it comes to the model class, the declaration should follow a specific structure as shown below:

export class Account {
    constructor(
        public activated: boolean,
        public authorities: string[],
        public email: string,
        public firstName: string,
        public langKey: string,
        public lastName: string,
        public login: string,
        public imageUrl: string
    ) {}
}

It is recommended not to define values outside of the constructor. You can declare the model class members as demonstrated in your example, without assigning any values:

export class TestModel1 {
  public currentPage: number;
  public hasNext: boolean;
  public hasPrev: boolean;
  public pageSize: number;
  public totalItems: number;

  constructor(data: any = null) {
    if(data !== null) {
      this.currentPage = data.currentPage;
      this.hasNext = data.hasNext;
      this.hasPrev = data.hasPrev;
      this.pageSize = data.pageSize;
      this.totalItems = data.totalItems;
    }
  }
}

If you wish to set default values, it is advisable to do so within the constructor for better code organization.

Update:

export class TestModel1 {
  public currentPage: number;
  public hasNext: boolean;
  public hasPrev: boolean;
  public pageSize: number;
  public totalItems: number;

  constructor(data: any = null) {
    if(data !== null) {
      this.currentPage = data.currentPage;
      this.hasNext = data.hasNext;
      this.hasPrev = data.hasPrev;
      this.pageSize = data.pageSize;
      this.totalItems = data.totalItems;
    }
    else {
      this.currentPage = 0;
      this.hasNext = false;
      this.hasPrev = false;
      this.pageSize = 0;
      this.totalItems = 0;
    }
  }
}

Incorporating default values inside the constructor is the recommended approach if defaults are needed.

Answer №2

One prominent concern highlighted in the query is that of repetition. The constructor contains duplicated properties, a practice that goes against the DRY principle essential for maintaining clean code.

To streamline the instantiation of a new instance of your domain object, consider implementing the following approach:

export class TestModel1 {
  public currentPage: number;
  public hasNext: boolean;
  public hasPrev: boolean;
  public pageSize: number;
  public totalItems: number;

  constructor(data: any) {
      Object.keys(data).forEach(key => {
         this[key] = data[key]
      });
  }
}

It's crucial to ensure that the input data object contains only the necessary properties, a task that can prove challenging depending on the data source.

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

The argument being passed, which is of type 'unknown[]', cannot be assigned to a parameter of type 'SetStateAction<never[]>'

Looking to add typing to a React component, but encountered a TypeScript error while trying to assign setCharacters(arrayOfObj); export type CharacterItem = { filepath: string; group: string; id: string; isClicked: boolean; } export typ ...

Guide to rounding values retrieved from JSON object using Math.round in Vue.js

I'm currently working on a Vue 3 component using the Composition API that fetches values from a JSON object and displays them on the screen. The component reads data from a local data.json file and returns these values to the template. The JSON file c ...

A Typescript interface designed for a higher-order function that returns another function

I am working with a StoryOptions object that includes a property called actionFn. This property, when invoked, will return a function utilizing function currying. The actionFn function must accept an object of type ActionBundle</code and should return ...

The name "Identifier" has already been declared before

I am currently working on a social network project to enhance my skills in nodejs and reactjs. While debugging the backend code for /signin using Postman, I encountered an error that prevents me from launching the node server. The error message displayed i ...

The Serverless Function appears to have encountered a critical error and has

Currently, I am in the process of deploying a backend Express app on Vercel. The server is primarily focused on handling a mailing API using Nodemailer. Below is my package.json: https://i.sstatic.net/uv3z7.png Here is my server.js file: import express ...

Developing a TypeScript WebSocket client that operates seamlessly in both browser and Node.JS environments

Currently, I am developing a typescript code that is intended to run in a web-browser environment but also needs to be tested with Node.JS. The client code I have created so far looks like this: import * as WebSocket from 'ws'; export class ...

Exploring Generics and Type Inference within TypeScript

(In reference to this question) I've developed a function that takes in a configuration object containing state definitions, essentially creating a state machine. For example: const machine = createStateMachine({ initial: 'inactive', s ...

TypeScript does not properly validate the types of defaultProps

When working with TypeScript 3.0, I consulted the documentation at https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html The recommendation is to use static defaultProps: Pick<Props, "name"> as an explicit type annotation ...

difficulties with creating Objects

While looking for examples of interfaces, I came across one that intrigued me. The example is provided below... using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace InterFaceDemo { interface IApple { ...

Is there a reason why this MD Bootstrap Snippet isn't functioning properly?

When zooming out to 25% or beyond, I noticed that the toolbar unexpectedly pops open and refuses to close. How can I prevent this from happening? I asked this question yesterday but unfortunately received only downvotes :( Appreciate any help provided ...

Unable to invoke JS function in Drupal 5 file

In my current project using Drupal 5, I have a specific .js file that is included using the code: drupal_add_js(drupal_get_path('module','MTM')."/include/JS_form.js"); Additionally, there is an element on the page: <a onclick="MTM ...

Initiate automatic video play delay on YouTube

Is there a way to delay the automatic start of a YouTube video, for example, by 20 seconds after the page loads? Here is an example without the delay: http://jsfiddle.net/qbqEA/ Thank you! ...

Updating a Vue component following an axios POST request

I'm currently working with Laravel 8 and Vue 3. In my SessionComponent.vue, there's a button that triggers an axios post method when clicked. I want this action to display my StudentComponent.vue. Even though I attempted to use vue-router for th ...

How can I include the "Referer" header in Angular Universal HttpClient XHR requests?

I am currently working on an Angular Universal SSR app that utilizes HttpClient to fetch data from the API server. So far, everything is functioning properly and I am able to render data server-side. However, I have encountered an issue regarding the clie ...

What causes my browser fingerprint to consistently remain unchanged?

declare var Fingerprint2: any; @Component({ selector: 'my-app', template: `Hello`, }) export class App { constructor() { new Fingerprint2().get(function(result, components){ console.log(result); // Device fingerprint as a hash va ...

Utilizing Array in ReactJS with the Power of Hooks

My current situation involves having an array of FooBar objects interface FooBar { foo: string, bar: string, correct: string, other: string[] } const [arrOfObj, setArrOfObj] = useState<FooBar[]>([ { "foo": "fool ...

Encountered a Milvus 2 Node.js SDK issue: "Error: TypeError: Class extends value undefined is not a constructor or null"

I'm currently developing an application using Nuxt.js and have opted for Milvus as the database. I'm aiming to implement a similarity search feature, but I've hit a roadblock with an error popping up in the browser console. The code snippet ...

Removing HTML elements using JQuery

Example: http://jsfiddle.net/axfsD/1/ I'm facing an issue with removing HTML tags from my webpage. Below are two examples where I have used the replace command to strip tags. However, it successfully strips the tags of the second button but not the f ...

Exploring CSS animations by utilizing the transform and color properties

I am currently working on a project that involves animating text (specifically "happy birthday to you") and a heart. The idea is for the heart to drop and hit each word one by one, turning them yellow upon impact. Once the last word is hit, the text shou ...

Challenges when upgrading from Ext JS 3 to Ext JS 4

I am looking to upgrade my code from Ext JS 3 to Ext JS 4. I used the Ext.Updater class in Ext JS 3, but I cannot seem to locate a similar functionality in Ext JS 4. Can anyone provide assistance with this transition? ...