Translate JSON to TypeScript class. If the property is an object and not present in the JSON, the class should contain an empty object

I am having trouble finding an appropriate title for the issue I am currently facing. Therefore, I will provide a detailed explanation of the problem.

I have a class named Model.ts

export class Model{
    a:ObjA;
    b:ObjB;
    c:ObjC;
    d:string;
    e:boolean;
    constructor(){
        this.a = new ObjA();
        this.b = new ObjB();
        this.c = new ObjC();    
    }
}

The subclasses are simplified for the purpose of this question ObjA.ts

export class ObjA{
    propA:string;
    propB:ObjD;
    constructor(){
        this.propB = new ObjD();
    }
}

ObjB.ts

export class ObjB{
    propA:string;
    propB:number;
}

ObjC.ts

export class ObjC{
    propA:string;
    propB:number;
}

Now, from a service, I receive the following JSON

{a:{propA:"some val"},c:{propB:12},d:"blah"}

My objective is to be able to assign the JSON to the class Model in such a way that I achieve this result

{a:{propA:"some val",propB:{}},b:{},c:{propB:12},d:"blah"}

When using Object.assign(new Model(),json), the output I get is

{a:{propA:"some val"},c:{propB:12},d:"blah"}

Notice the absence of b here. Also, a does not include propB

Therefore, my question is, How can I map the JSON in such a way that if any property, which is an object, is missing in the JSON, an empty object will be created? (I am willing to use lodash and similar utilities)

P.S: The scenario here is that I am developing an Angular2 application in which the properties are entered using a form. If I use the elvis operator in HTML (obj?.prop), the value for that property is never set because the object does not have that property. If I do not use the elvis operator, then the age-old undefined is returned.

Sample form:

...
    <input [(ngModel)]="model.a.propA"/>
    <input [(ngModel)]="model.a.propB"/>
    <input [(ngModel)]="model.b.propA"/>
    <input [(ngModel)]="model.b.propB"/>
    .
    .
    .
...

Related *.ts component

class Component implements OnInit{
  ....
  model:Model = new Model();
  ngOnInit(){
    getData().subscribe(res=>Object.assign(model,res));
  }
}

Answer №1

To merge two objects, you can use Object.assign along with a default object that you define. By combining the properties of both objects, the JSON data will override the defaults:

let defaultObj  = { a: "default value a", b: "default value b" };

let json = { a: "json value a" };

let model = Object.assign({}, defaultObj, json);

Result:

{a: "json value a", b: "default value b"}

Keep in mind that this method only creates a shallow copy of the properties from defaultObj and json. If your properties include objects, you might consider deep cloning the merged result from Object.assign to avoid sharing the same object across different parts of your code.

Edit: Some utility libraries like underscore offer functions such as _.merge that can both merge and deep clone objects.

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

When iterating through a list of strings using ngFor, I am unable to directly access or manipulate the individual items

Within my model, I have a list of strings. <span *ngFor="let item of model; let i = index"> <input #inputField type="text" [name]="name + '_' + i" [(ngModel)]="item" /> </span> The code snippet ab ...

Passing Selected Table Row Model Data to Backend in Angular 7

My goal is to send the selected data in a table row, which I select through a checkbox, to the server. However, I'm unsure about how to handle this via a service call. While I have the basic structure in place, I need assistance with sending the items ...

MUI is designed to only manage either onBlur or onKeyPress, but not both simultaneously

Currently, I am working on a project with TypeScript and Material-UI. My main goal is to handle both the onBlur event and the onEnter key press event for a TextField component. Here's the scenario: I have incorporated this text field into a menu. Whe ...

Is it possible to parse JSON in C# code without predefining the fields?

I am currently developing a REST API for my project using Visual Studio 2013 with C# and ASP.NET, and I could use some advice. When the webpage executes a POST request, I send various fields as a JSON object. By defining a data transfer object in my C# co ...

Is it possible to maintain the Spring default login page while turning off CSRF protection?

I have been working on a Spring+Angular site and the default login page was functioning well for me initially. The issue arose when I needed to turn off CRLF validation to be able to make POST requests from my Angular application, so I disabled it. Unfor ...

Utilize JSON categories to assign groups to TextFields or Selects according to a JSON data attribute

I have retrieved multiple JSON groups from an API, each containing one or more questions objects. My goal is to display each question along with its corresponding response in a MUI TextField or Select component, based on the value of QuestionType. Current ...

What could be causing the delay in the execution of Redux dispatch?

When I open a file and parse it, the dispatch into redux state takes longer than anticipated. It seems like the dispatch itself is taking several hundred milliseconds more than the reducer. After opening and parsing the file, the following dispatch is mad ...

Add a JSON file containing an image path as a value into a CSS background property

I currently have a MongoDB database containing documents with 'img' values structured as follows: "img": "../folder/img.jpg" Would it be feasible to utilize this string in my CSS for modifying the background image? This is essential because I n ...

I'm interested in developing a feature that monitors a specific attribute and triggers a function once that attribute hits the value of 100

I am working on a function that will refresh the view once the percentage changes reaches 100: The value is stored in this variable: this.uploadPercent = task.percentageChanges(); This is the function I plan to implement : refreshView(){ Once this.uplo ...

Simple steps to transform the "inputs" syntax into the "@Input" property decorator

There's this code snippet that I need to modify: @Component({ selector: 'control-messages', inputs: ['controlName: control'], template: `<div *ngIf="errorMessage !== null">{{errorMessage}}</div>` }) Is the ...

Encountering an issue with testing CKEditor in Jest

Testing my project configured with vite (Typescript) and using jest showed an error related to ckeditor. The error is displayed as follows: [![enter image description here][1]][1] The contents of package.json: { "name": "test-project" ...

Error: The Select2 query service is not available

I am looking to enhance the search functionality for my select2 dropdown. My goal is to trigger a service call with the search parameters once 3 characters are typed into the search field. However, when I try to select an option from the dropdown, I encou ...

Building a list of dictionaries in Python by iterating through a data source

Currently, I am extracting data from an Excel file and aiming to convert it into a JSON format. To achieve this, I am looping through the rows and creating a dictionary for each row. These dictionaries are then added to a list, where the entire list will r ...

Handle malformed Json by deserializing and returning empty arrays

Recently, I have been using VB.NET Http Requests to retrieve data from a webservice. Initially, the data was sent in a structured format like this: [ { "id": 7532, "nome": "LABOR INC.", "isClient": false, "personality": { ...

Event typeORM on afterUpdate in NestJS

After every update of my data in the log table, I want to insert an entry into another table. To achieve this, I have created an EntitySubscriberInterface. The event is triggering correctly, but the entity array does not include the updated id. async afte ...

What is the best way to create props that can accommodate three distinct types of functions in TypeScript?

I have been encountering a problem with the last function in my props interface that is supposed to support 3 different types of functions throughout the application. Despite adding parentheses as requested, I am still facing errors. // In Parent compon ...

What is the best way to create buttons corresponding to the total number of "postId" properties in an array retrieved from an API call in Angular 10 using the "ngFor" directive?

export class AlphaComponent implements OnInit { apiData=[]; //array that stores API data constructor(private helpService:HelpService){ }; ngOnInit(){ this.fetchData() }; fetchData(){ this.helpService.getPostId().subscribe(( ...

What is the best way to utilize RxJS for grouping data results, ordering them, and selecting specific items, while also retrieving data from the RxJS

Could you assist me in creating a query that groups by smileTypeId and counts rows by id, then orders by count in descending order and takes the top 2? Retrieve the Smiles array from the RxJS store. View Screenshot Get Post Smiles posts = [ { &quo ...

Troubleshooting conflicting dependencies in Angular 17

After setting up a new project with Angular 17, I encountered an error: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail ...

Oops! An issue occurred: The value 'NgxMatDrpModule' was not expected in the specified file path: node_modules/ngx-mat-daterange-picker/ngx-mat-daterange-picker.d.ts

Encountered an error while building an Angular 7 app using the command ng build --configuration=dev. The exception shows a single quote prefixed to NgxMatDrpModule. Even after deleting node_modules, package-lock.json and reinstalling node modules, the issu ...