TL;DR:
- A specific angular interface was linked to
HttpClient.get()
responses. - The responses were transformed into a seemingly general
object
type. - Even though attributes like
id
andtitle
were not defined on the interface, they were still accessible in the response object as well as in the .html file (e.g.
.<p>Title is: {{message?.title}}</p>
- If an interface acts as a contract, should it not restrict some of this behavior?
Transitioning from a Java background to Angular 4 where I encountered issues with type safety in HttpClient
. According to this guide, one can use an interface when making a call to http.get<>
to validate the HTTP response.
Let's take a simple interface with just a single field foo
:
export interface FooInterface{
foo: string;
}
Following the guidance mentioned above, we can easily connect this interface with a response:
export class RestComponent {
message: FooInterface;
http.get<FooInterface>('/api/items').subscribe(data => {
this.message = data;
console.log(this.message);
console.log(typeof(this.message));
console.log(this.message.foo);
});
Here's the issue: when I hit an API that doesn't include a foo
field. The real API provides two fields instead: id and title. Surprisingly, even though the expected field was missing, a data object was still created:
https://i.sstatic.net/xW9g9.png
This data object now contains fields id
and title
. Trying to access data.foo
will return undefined
.
Moreover, although the interface stops me from directly accessing these id and title fields, they can still be accessed using calls like data['id']
and referenced in the HTML file.
<h1>
id: {{message.id}}
<br>
title: {{message?.title}}
</h1>
Surprisingly, this works! Essentially, the only thing the interface appears to prevent is something like:
`this.message.title`
That seems alright... but considering that these fields can still be accessed using this.message['title']
or in html files, what's really the purpose of the interface?