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

VS Code is throwing an Error TS7013, while Typescript remains unfazed

In my Typescript/Angular project, I have the following interface: export interface MyInterface { new (helper: MyInterfaceHelpers); } After compiling the project, no errors are shown by the Typescript compiler. However, VSCode highlights it with squiggl ...

Cricket score update features on the client side

Looking for assistance with client-side code development! I am currently working on an Android application using Ionic that involves live cricket scores. I have purchased a cricket API and understand how to connect to it using Node.js on the server side. ...

Having trouble locating the export in the TypeScript module

Having a situation where there is a file with an exported object: let btypes:{[key:string]:any} = { "key1":val, //... } export {btypes} I even attempted to use export default btypes Upon importing it using: import {btypes} from "../types& ...

Can the Rxjs library's Observables of() function be used to output multiple values?

I am inquiring about this because I came across in the Angular documentation that of(HEROES) returns an Observable<Hero[]> which emits a single value - an array of mock heroes. If I cannot use of(), do you have any alternative suggestions for me? I ...

Is there a gap in the Nativescript lifecycle with the onPause/onResume events missing? Should I be halting subscriptions when a page is navigated

My experience with NativeScript (currently using Angular on Android) has left me feeling like I might be overlooking something important. Whenever I navigate to a new route, I set up Observable Subscriptions to monitor data changes, navigation changes, an ...

Using the up and down arrow keys on the keyboard to navigate through a mat-form-field-infix field in

Is there a way to simulate keyboard inputs for the up and down buttons in a drop-down list while working with mat-form-field-infix? I attempted using Robot framework, but it seems that the drop-down list does not appear unless I manually interact with it ...

Issue encountered while trying to determine the Angular version due to errors in the development packages

My ng command is displaying the following version details: Angular CLI: 10.2.0 Node: 12.16.3 OS: win32 x64 Angular: <error> ... animations, cdk, common, compiler, compiler-cli, core, forms ... language-service, material, platform-browser ... platfor ...

waiting for the import statement in a React/NextJS/Typescript project to resolve

While working on my node.js development server, I encountered a problem with the following code: import { useRouter } from 'next/router' import nextBase64 from 'next-base64'; const Load = () => { const router = useRouter() co ...

What is the best way to create a generic array and combine properties?

I have a scenario where I have two objects defined as one and two, each containing props. These objects are then stored in an array called packages. const one = { props: { num: 2 } } const two ={ props: { nam ...

Get the file without specifying type in request - Angular

Is it possible to download a file solely through the response without specifying a responsetype in the header? I am looking for a way to download the file without including any additional parameters in the header. ...

The primary export is not a React Component on the specified page: "/"

Encountering an error while attempting to use compiled code from Typescript to Javascript with Next.js Error message: The default export is not a React Component in page: "/" Seeking assistance on how to resolve this issue. Any help would be greatly appr ...

Utilize Angular CDK to attach an overlay to a specified clicked element

I am currently attempting to create a personalized popover for a table cell that displays the details of the cell when clicked, similar to the mdBoostrap popovers. Here is the app I have so far: https://stackblitz.com/edit/angular-m5rx6j The Popup compon ...

Top method for converting scrolling into an element

When trying to create a scrollable element, I attempted the following: .scroll-content { overflow: hidden; } .scrollabe { overflow-y: scroll; } <ion-content> <ion-grid style="height:100%" *ngIf="plat && ticket"& ...

Utilizing a library that solely enhances the functionality of the Array object

I have a library with type definitions structured like this: declare global { interface Array<T> { addRange<T>(elements: T[]): void; aggregate<U>(accumulator: (accum: U, value?: T, index?: number, list?: T[]) => an ...

Adjust the size of an Angular component or directive based on the variable being passed in

I'm looking to customize the size of my spinner when loading data. Is it possible to have predefined sizes for the spinner? For example: <spinner small> would create a 50px x 50px spinner <spinner large> would create a 300px x 300p ...

Clicking on a single checkbox causes the entire input to become deactivated due to the way the system is

I'm encountering a puzzling issue that has me feeling like I know the solution, yet I don't. I set "State" to [checked]. The problem arises when, upon turning it into a map and clicking just one checkbox, the entire selection is clicked. To addre ...

Obtain data from a single module and incorporate it into a different one

In my Angular 2 application, I am dealing with two component files - home.ts and folder-selector.ts. Within the folder-selector.ts file, there is a variable named pathToNode. I am trying to figure out how to access this value from within the home.ts file ...

Utilizing ngModel to map object arrays in Angular 4 within template-driven forms

Currently, I am working on a template-driven application and wanted to share my project structure with you: parent parent.component.ts parent.component.html child child.component.ts child.component.html child.ts child.ts: export class child ...

Discovering the dimensions of a video in Angular 2 using TypeScript

To determine whether the video is portrait or landscape, I am attempting to retrieve the height and width of the video using the following method: import { Component, OnInit, AfterViewInit } from '@angular/core'; @Component({ selector: ' ...

Angular Material - Data Table Kit

Struggling with setting custom styling for a mat-table in Angular Material. I want to adjust the border radius of the table and change the spacing inside to "space-between". The design I'm aiming for is shown here: Design Any tips or suggestions woul ...