2

I have a .net core web api that returns a list of ethnicities with a number of properties. Using the angular httpclient I call the api and return the data. When I subscribe in angular and cast the data to a much more simple interface, the full object is mapped / cast. Not what I was expecting.

Here is what I have:

export interface IEthnicity {
    id: any;
    ethnicity: string;
}
export class AppComponent {
  ethnicities: IEthnicity[] = [];

  constructor(private svc: MyServiceService) {
    this.svc.getList().subscribe(
      resp =>{
        this.ethnicities = resp as IEthnicity[];
        console.log(this.ethnicities);
      }
    );
  }
}

I was expecting my ethnicities array to hold a list of the same type as the interface but it is an array with the same type as returned by the web api.

e.g.

0: {Id: 'abc1', OrganisationId: 'org1', Ethnicity: 'Indian', IsDeleted: false }
1: {Id: 'abc2', OrganisationId: 'org1', Ethnicity: 'White', IsDeleted: false }
2:
   Ethnicity: "Chinese"
   Id: "abc3"
   IsDeleted: false
   OrganisationId: "org2"
3: {Id: 'abc4', OrganisationId: 'org3', Ethnicity: 'Irish', IsDeleted: false }
4: {Id: 'abc5', OrganisationId: 'org2', Ethnicity: 'Arab', IsDeleted: false }

Notice the properties do not match the interface, The capitalisation of the first letter of the name of the property and the double quotes " instead of single quotes ' around the expanded array item values.

Regardless of what is actually coming back from the api, the resp as IEthnicity[] should cast the values to the two interface properties only. What am I missing?

Update

For anyone who has the same problem, a simple answer is to use the map function in rxjs. Don't forget to include the following import import { map } from 'rxjs';

    svc.getList().pipe(
      map((list: any) => list.map((ethnicity: any) => ({ id: ethnicity.Id, ethnicity: ethnicity.Ethnicity }) as IEthnicityType ))
    )
    .subscribe(
      data => {
        this.ethnicities = data as IEthnicityType[];
      }
    );

Hope this helps

4
  • 3
    TypeScript doesn't have "casting", or at least the term "casting" is so loaded as to be best avoided. TypeScript has type assertions, which is where you tell the compiler that an expression will actually be of some type, generally because the compiler can't figure that out itself. TypeScript's type system is (almost) completely erased; no type annotation, interface, assertion will survive to the emitted JavaScript. foo as Bar becomes just foo at runtime. Commented Feb 12, 2022 at 0:49
  • See stackoverflow.com/questions/60218424/… Commented Feb 12, 2022 at 0:51
  • I'm inclined to close this as a duplicate of the previous question, and of stackoverflow.com/questions/50839597/…, and of stackoverflow.com/questions/63940196/… . If you want this question to remain open and get its own answer, please elaborate on what the difference is. Commented Feb 12, 2022 at 2:10
  • 1
    I agree @jcalz, I have flagged as a duplicate. Thanks for pointing me in the right direction. I didn't realise the difference between the cast and assertion of this command before you explained. Thanks Commented Feb 12, 2022 at 10:44

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.