简体   繁体   中英

How do I ensure typescript interface properties are uppercase after I obtain result in angular 5?

I have a web api that returns the following result

{
  "customerContactID": 1,
  "customerID": 1,
  "firstName": "james",
  "lastName": "smithman",
  "primaryEmail": "james@gmail.comm",
  "primaryPhone": "8788494677",
  "isPrimaryContact": true
}

and I have an angular 5 app that defines an interface as

    interface CustomerContact {
      CustomerContactID: number;
      CustomerID: number;
      FirstName: string;
      LastName: string;
      PrimaryEmail: string;
      PrimaryPhone: string;
      IsPrimaryContact: boolean;
  }

and return the result using

            this.http.get<CustomerContact>(url).subscribe(result => {
            console.log("CustomerContact obtained");
            console.log(result); // prints lowercase properties
            this.customerContact = result;
        }, error => console.error(error));

Unfortunately, when i log the result, I can see that the properties have all been lowercased, so I cannot do something such as

this.currentCustomer = result.CustomerID;

Since it results in undefined. However, I need to be able to set a variable value to the value obtained from the api result, specifically result.CustomerID. Typescript does not allow me to do

this.currentCustomer = result.customerID;

since it results in

TS2551: Property 'customerID' does not exist on type 'CustomerContact'. Did you mean 'CustomerID'?

How do I set the value of a variable to the value of result.customerID despite the compiler [at-loader] error?

I cannot change the API contract at all, also, my typescript interface must have UpperCase for property names.

UPDATE 1 as @pArth savadiya mentioned below, It looks like I can do this 使用任何类型

Although, Im not sure if the repercussions, if any

I dont believe this is a duplicate of Convert returned JSON Object Properties to (lower first) camelCase since that question has a result model that has uppercase properties, which is not what I have here.

UPDATE 2 After some close observation ,I realized that the big issue here was the MISTMATCH between the api response property casing and the angular/typescript casing mismatch. Without them being the same, it causes issues and forces odd workarounds. The solution simply was to match the interface casing with the response casing for this particular request. Its that simple. Thank you everyone.

In your code you tightly coupled HTTP response result with your typescript interface(CustomerContact) use instead of it.

 this.http.get <any> (url).subscribe(result => { console.log("CustomerContact obtained"); console.log(result); // prints lowercase properties this.customerContact = result; }, error => console.error(error)); 

then you can able to write this.currentCustomerID = result.customerID;

or you can try like this: this.currentCustomer = result["customerID"];

In comparison with JavaScript, TypeScript helps to make explicit choices about types ie about the design of the code. Your question is indeed a matter of design decisions of your Angular application.

It helps to reason considering layers in the architecture: the WebApi, the service fetching its data and the UI components are not in the same layers.

You can decide to have for the “CustomerContact”:

  1. The same type in all layers:
    • This type is defined by the WebApi so all fields are in camelCase: interface CustomerContact { customerContactID: number… } and you can do http.get<CustomerContact>(url) .
    • It's cheap in the short term but expensive in the long run because any change in the WebApi signature can induce a lots of changes in several files in all layers!
  2. Distinct types:
    • The WebApi method returns a DTO : interface CustomerContactDto { customerContactID: number… } and http.get<CustomerContactDto>(url) . Don't use the type any if you want to keep the type safety provided with TypeScript.
    • The domain layer deals with a CustomerContact with whatever fields you likes, in whatever case you wants (camelCase, PascalCase, …) even if PascalCase in more a C# convention than a TypeScript one.
    • The service containing the http.get<CustomerContactDto>(url) will do the mapping between both types to return a CustomerContact , as part of an ACL . This mapping can be done simply field by field: const customerContact = new CustomerContact(); customerContact.CustomerContactID = result.customerContactID; … const customerContact = new CustomerContact(); customerContact.CustomerContactID = result.customerContactID; … const customerContact = new CustomerContact(); customerContact.CustomerContactID = result.customerContactID; … .

In your interface change

CustomerID: number;

to

customerID: number;

It will work as you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM