Rxjs - Converting JSON data into a TypeScript interface

While navigating through this new environment, I encountered the need to make a Web API call. The abundance of versions and options can be overwhelming. Nevertheless, I managed to find a solution that works well. Although I understand that defining "best practice" is somewhat subjective, I am curious if there is a more straightforward approach to accomplish this task.

My desired response format looks like this:

export interface AuditDetail {
  updatedAt: Date;
  updatedBy: string;
}

This is the server-side model:

[DataContract]
public class PlanHistory
{
    [Key]
    public int Id { get; set; }

    [DataMember]
    [MaxLength(50)]
    public string UpdatedBy { get; set; }

    [DataMember]
    public DateTime UpdatedAt { get; set; }
}

And here is the Angular service I wrote:


getAuditDetails(planId: number, fieldName: string, fieldValue: string): Observable<AuditDetail> {
    //return of({ updatedAt: new Date(), updatedBy: "Hawchorn" }); //Tooltip displays data

    interface PlanHistory    //Created because couldn't figure out how to directly map from Json to an Audit Detail. 
    {
      UpdatedAt: Date;
      UpdatedBy: string;
    }

    this.log("Retrieving Audit Details");
    return this.http
      .get<PlanHistory>(this.webApiUrl +
        "PlanHistories?planId=" +
        planId +
        "&fieldName=" +
        fieldName +
        "%20&fieldValue=" +
        fieldValue).pipe(map((response: PlanHistory) => {
          return <AuditDetail>{ updatedAt: response.UpdatedAt, updatedBy: response.UpdatedBy };
      }));
  }

The current method is effective, but I find creating that intermediate interface bothersome.

How can I achieve the same result without needing the additional interface?

Answer №1

If you wish for the Web API to provide camelCasing output, eliminating the need to alter casing yourself, refer to JSON and XML Serialization in ASP.NET Web API:

To ensure JSON property names are in camel case without modifying your data model, apply the

CamelCasePropertyNamesContractResolver
to the serializer:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

Subsequently, your code will appear as follows:

getAuditDetails(planId: number, fieldName: string, fieldValue: string): Observable<AuditDetail> {
    this.log("Obtaining Audit Details");
    return this.http
        .get<AuditDetail>(`${this.webApiUrl}PlanHistories?planId=${planId}&fieldName=${fieldName}%20&fieldValue=${fieldValue}`);
}

Answer №2

It is recommended that you infer the mapping, as the only difference lies in the casing of your names. Would it be possible for you to update them to match?

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

Can you tell me the meaning of NGX and how it is commonly utilized?

Can you explain NGX to me? I frequently come across it paired with module names in Angular applications. What exactly is NGX and what purpose does it serve? ...

The data structure '{ recipe: null; }' cannot be matched with type 'IntrinsicAttributes & Recipe'

Currently, I am working on an app that integrates ChatGPT to fetch recipes based on user-input ingredients. After receiving the JSON response from CGPT, I aim to display a Recipe "Card" component. However, I encounter an error titled above when attempting ...

Changing the size of a div component using Angular 6

Currently, I am working on implementing Angular's element resize feature. I am utilizing this library: https://github.com/mattlewis92/angular-resizable-element Here is my custom module: import { ResizableModule } from 'angular-resizable-elemen ...

"Exploring the process of creating a custom type by incorporating changes to an existing interface

One of the challenges I'm facing is defining an object based on a specific interface structure. The interface I have looks like this: interface Store { ReducerFoo : ReducerFooState; ReducerBar : ReducerBarState; ReducerTest : ReducerTestSt ...

Setting up the Font Awesome Pro version in Angular using the Font-Awesome package

The process of installing the pro version of Angular Font-awesome began with setting up my registry using these commands: npm config set "@fortawesome:registry" https://npm.fontawesome.com/ && \ npm config set "//npm.fontawesome.com/:_authTo ...

Different Angular 2 components are resolved by routes

Consider this scenario: Upon navigating to the URL /product/123, the goal is to display the ProductComponent. This is how it's currently configured: RouterModule.forRoot([ { path: 'product/:productId', ...

How can one retrieve the selected value from a dropdown menu in Angular?

Objective: My goal is to create a dropdown menu where users can select a value, which will then dynamically change the address of the website based on their selection. Issue: Although I managed to make the address change upon selection, it did so for ever ...

Running frontend and backend applications together in a Docker container

As I work on integrating my frontend in Angular with the corresponding backend in Spring Boot, both as standalone projects, I am now looking to transition them into production mode. This has led me to consider hosting each project in separate docker contai ...

Autoformatting files with ESLint on save

I'm encountering an issue where Visual Studio Code is saving my file in violation of the rules specified in my eslint configuration when using eslint and prettier for formatting. module.exports = { env: { browser: true, es2022: true, nod ...

Navigating with Angular: Displaying child components on separate pages

When I click on a button in match-controls.component.html, I want my child component (BasicStatControlComponent) to load on a new page. However, the component is rendering directly below the buttons instead. How can I fix this issue? Any help would be appr ...

What is the best way to avoid curly braces in an Angular template?

If I need to show the following string, including the {{ }}, in an Angular 2+ template: Hello {{name}}, how are you?" Note: The entire string will be hardcoded, not from a variable. What is the optimal method to encode the curly braces so they are not ...

Unable to access the jumbotron in Angular with Bootstrap 5

Recently, I set up a brand new Angular installation and included Bootstrap 5 using the following command: npm install bootstrap --save After that, I updated the lines in the angular.json file to: "styles": [ "node_modules/bootstra ...

Conflicting Versions of NPM Packages

Trouble with conflicting package versions: https://i.sstatic.net/TLy5m.jpg I'm new to using NPM and I'm facing issues while trying to set up an Ionic 2 application. I'm struggling to resolve the package version conflicts. Before running th ...

Two storage locations exhibit distinct behavior when it comes to the favicon

After moving my repository to a new origin and pulling it into a different directory on my computer, I encountered an issue with my .NET Core API and Angular client. The problem is that the new instance of the repository, after being built, does not disp ...

Evaluating whether an imported function, which serves as a dependency of an adapter, is being invoked with accurate parameters within the adapter using the Jest testing framework

Here is how my test looks import { SlugGeneratorAdapter } from './slug-generator-adapter' import slugify from 'slugify' describe('SlugGenerator Adapter', () => { test('Should call the slug generator with the correct ...

The Angular Material Table is reporting an error: the data source provided does not conform to an array, Observable, or DataSource

Having some trouble with an Angular Material table, as I'm encountering an error preventing me from populating the grid: Error: Provided data source did not match an array, Observable, or DataSource search.service.ts GridSubmittedFilesList: IGridMo ...

Angular4 - Div with ngIf doesn't respond to click event

I'm attempting to add a click event to a specific div. Within this div, there is another div that is dynamically generated based on a Boolean condition that I receive as input. Unfortunately, in this case, the click event is only functioning when clic ...

The issue arises when the mat-panel-description is not properly aligned with the shrinking panel

Within my HTML, I have a mat-panel with a description that is populated by a variable from the TS file. However, I am encountering an issue where if I shrink the panel and the description is too long, the text is cut off at the top and bottom. Is there a w ...

Utilize the data structures and variables from one module to enhance the functionality

Currently, I am utilizing Babylonjs with Rollupjs in conjunction with typescript. https://i.sstatic.net/2L3bY.png When importing Babylonjs like so: import { ArcRotateCamera, Engine, SceneLoader, Vector3 } from "babylonjs"; I am able to access all the t ...

Error: Jest + Typescript does not recognize the "describe" function

When setting up Jest with ts-jest, I encountered the error "ReferenceError: describe is not defined" during runtime. Check out this minimal example for more information: https://github.com/PFight/jest-ts-describe-not-defined-problem I'm not sure what ...