Setting default values for class members in Typescript is important for ensuring consistent behavior and

My model is pretty straightforward:

export class Profile extends ServerData {
  name: string;
  email: string;
  age: number;
}

Whenever I make a server call using Angular 4's $http, I consistently receive this response:

{
  name: string;
  email: string;
}

The property age is missing.

Is there a way to incorporate my model and set a default age if it's not included? I'd rather avoid creating separate models if possible.

I don't want to make the age an optional property - I require it, even if it means having an incorrect default.

UPDATE:

This is the request I'm sending to the server:

results-manager.component.ts:

this.resultsManagerService.getResults(this.config.request.action, this.pagingAndSorting, this.args).subscribe(
  results => {
    this.results = this.results.concat(results as Profile[]);

results-manager.service.ts:

getResults(action: string, pagingAndSorting: PagingAndSorting, args: string[]): Observable<Profile[]> {
return this.apiService.callServer(
  pagingAndSorting,
  action,
  ...args );

}

The request goes through successfully and I get the response, but any default values I define (as suggested by @msanford's answer) are removed when I receive the response in the component. Similarly, adding a constructor to the model (like Mike Tung's answer) doesn't work either.

It seems like the backend response completely overrides the model instead of just assigning the values.

How can I ensure that it only assigns the values to the model without removing any existing ones?

Answer №1

Absolutely, without a doubt, you can achieve this without the need to incorporate a class constructor.

export class Profile extends ServerData {
  name: string;
  email: string;
  age: number = 0;
}

The feature that sets a class apart from an interface is the capability to define default values.

To make this function properly, you must include new Profile() in your code somewhere; otherwise, a class instance won't be generated and defaults won’t be established. This is because the TypeScript above will translate into the following JavaScript:

var Profile = /** @class */ (function () {
    function Profile() {
        this.age = 0;
    }
    return Profile;
}());

Hence, just utilizing it for type assertion during compilation isn't enough to assign a default value at runtime.

Witness it in action on the TypeScript Playground.

Answer №2

The issue of properties being overwritten is a result of TypeScript's type erasure. During runtime, TypeScript cannot determine the types of objects assigned to its variables, which may be confusing if you are familiar with languages like Java or C#.

This is because ultimately, TypeScript compiles down to JavaScript, and JavaScript does not enforce strict type checking.

To ensure that profile objects always have an age property, one approach is to create custom objects and then copy values from the response. This is a common strategy for mapping wire format data to domain objects.

Firstly, define your domain model by creating a Profile class with a default age property:

 export class Profile {
        constructor(
            public name: string,
            public email: string,
            public age: number = 0) { }
    }

Next, map the response data to instances of the domain model:

this.resultsManagerService.getResults(this.config.request.action, this.pagingAndSorting, this.args).subscribe(
  results => {
    let res = (results as Profile[]).map((profile) => new Profile(profile.name, profile.email, profile.age));
    this.results = this.results.concat(res);
 });

Answer №3

All you have to do is utilize a constructor in your code.

export class Details extends DataHandler {
  title: string;
  description: string;
  price: number;

  constructor(title: string = '', description: string = '', price: number = null) {
    this.title = title;
    this.description = description;
    this.price = price;
  }
}

By using this constructor, default parameters will be set for any missing values.

Answer №4

It's not possible to automate this process, but you can establish defaults for a function (such as the class constructor):

function createProfile({ name = '', email = '', age = 0 }) {
  const individual = new Profile;
  individual.name = name;
  individual.email = email;
  individual.age = age;
  return individual;
}

So when you use

createPerson({ name: 'name', email: 'email' })
, it will generate a Person object with age = 0.

Answer №5

export class Cell {
    constructor(
        public title: string = "",
        public rows: number = 1,
        public cols: number = 1
    ){ }
}

export class Desk {
    public cell1 = new Cell()
    public cell2 = new Cell()
    public cell3 = new Cell()
    
}

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

Is there a method to create a typecheck for hasOwnProperty?

Given a certain interface interface Bar { bar?: string } Is there a way to make the hasOwnProperty method check the property against the defined interface? const b: Bar = { bar: 'b' } b.hasOwnProperty('bar') // works as expected b. ...

Remove all `Function.prototype` methods from Typescript

Can a callable object (function) be created without utilizing Function.prototype methods? let callableObject = () => 'foo' callableObject.bar = 'baz' callableObject() // 'foo' callableObject // {bar: 'baz'} call ...

A deep dive into TypeScript: enhancing a type by adding mandatory and optional fields

In this scenario, we encounter a simple case that functions well individually but encounters issues when integrated into a larger structure. The rule is that if scrollToItem is specified, then getRowId becomes mandatory. Otherwise, getRowId remains option ...

At what point does a vulnerability in a React or Angular library become a serious threat?

As a cybersecurity student, I have noticed numerous CVEs related to libraries used in React and Angular. One example is: │ Critical │ Prototype Pollution in minimist │ ├────────────── ...

Error: FullCalendar does not display a header for the timeGridWeek view when the dates fall

Currently, I am integrating fullcalendar 5.5.0 with Angular 10. After migrating from fullcalendar v4 to v5, I noticed an annoying issue where the header for the date before the validRange start is no longer displayed: These are the parameters being used: ...

Unleashing the Power of Firebase Service in Angular Components: A Guide to Effective Unit Testing

I am currently working on testing my Create-User-Component which relies on an Auth Service that includes methods like 'login, logout,' etc. The Auth Service imports both AngularFireAuth and AngularFirestore, and it is responsible for handling da ...

How to automatically disable a button in reactjs when the input field is blank

I have a component called Dynamic Form that includes input fields. The challenge I am facing is how to disable the submit button when these input fields are empty, although the validateResult function fails to return false. import cn from "classname ...

Angular 8 encountered an error in content_script.js at line 71. The error was classified as a LEVEL: ERROR within the MODULE:

I am currently working on an Angular 8 application with Dotnet Core, and I have encountered a strange error message in the developer's console recently: content_script.js:71 LEVEL: ERROR | MODULE: LEAKED_CREDENTIALS | SESSION: a1293cfe | MESSAGE: &qu ...

Leverage functionalities from the rxjs npm package within an Angular application without the need for npm install

In the midst of updating my Angular 4 application to use rxjs version 6.3+, I discovered that many changes in rxjs are causing issues with my existing codebase. One of the new features we need to implement requires this update, but it's proving to be ...

Assembly of Components

As someone new to angular, I am currently in the process of building an angular2 application. My goal is to dynamically create a series of DOM components using the data provided below: // Class construct with properties sorted alphabetically export class ...

The value calculated by Auto does not display as a valid number in Angular 8 until it has been manually edited

Having an issue with a form submission for invoicing. The total value field, which is auto-calculated based on quantity and unit price, does not show up as numeric data in the backend onSubmit event unless I manually interact with it by adding something ...

The Vue instance seems to be unable to recognize the shims-vue.d.ts file

I encountered an issue with my Vue file. Here is the code snippet: import Vue from 'vue'; import VueRouter from 'vue-router'; export default Vue.extend({ name: 'MyComponentsName', methods: { doRedirect() { this. ...

Trouble merging latest values using RxJS combineLatest in Angular 12

Having difficulties with combining multiple filter values in API call. I have 3 filter values and want to make a combined call when there is a selection change, but only one value is showing up in 'combineLatest'. Please guide me on where the iss ...

Utilizing a service within NestJS

I'm currently in the process of updating some older code and I have created a service that I want to inject into the constructor of a class. There are two key points to consider about this particular class. The first point is that it is instantiated b ...

The query for PrManagerBundleEntityeb_user is missing the identifier id

In an attempt to delete an object by its ID from the database using the following code in the frontend, I encountered an issue where the link does not function as expected. Here is the error message that I received: The identifier id is missing for a quer ...

Having trouble receiving a response from the websocket using RxJS in Node.js with Angular

Currently experimenting with setting up a WebSocket using rxjs webSocket I have managed to create a node server without any errors, but it is not sending messages to the server or connected users When I switch to 'ws://echo.websocket.org/', I c ...

Angular 2 Error: Unresolved Promise rejection - Unable to assign value to reference or variable

I'm currently working on an Ionic 2 app that includes a barcode reader feature. However, I encountered the following issue while trying to display data: Unhandled Promise rejection: Cannot assign to a reference or variable! ; Zone: ; Task: Promi ...

The usage of @Inject('Window') in Angular/Jasmine leads to test failures, but removing it results in code failures

Currently, I am encountering a dilemma related to using Angular's @Inject('Window') within a web API service. This particular issue arises when the Window injection is utilized in the service constructor, leading to test spec failures in the ...

Steps for configuring type definitions for an Apollo error response

Apollo's documentation explains that an error response can take the following form: { "data": { "getInt": 12, "getString": null }, "errors": [ { "message": "Failed to get s ...

Redirecting to child routes based on conditions

I encountered a situation where I need to lazily load child routes and display them conditionally: const routes: Routes = [ { path: '', component: MainComponent, canActivate: [AuthGuard], children: [ { path: &apos ...