I have predefined properties in interface as below:
export interface User {
userID : number;
userName : string;
userAge : string;
}
Also, I have service which returns some dummy data from some dummy REST api.
getUsers(){
return this.http.get("https://fakerestapi.azurewebsites.net/api/Authors").toPromise();
}
and in component I am consuming this service and convert data to userlist as per below code:
_service.getUsers().then(i => { this.userList = i as User[]; console.log(this.userList) });
as you can see, I used 'AS' to convert response to my respective user[] array.
ISSUE:
dummy REST api retruns following data
{
"ID": 1,
"IDBook": 1,
"FirstName": "First Name 1",
"LastName": "Last Name 1"
}
and user class doesn't have property of ID, IDBook etc. still when I check console, it automatically change the definition of User class and shows all the data although properties are not matched.
Link: https://stackblitz.com/edit/angular-pryy3f?file=src%2Fapp%2Fappservice.service.ts
As per my understanding only match properties should be displayed not all.
In typescript as
keyword is not a type casting but a type assertion. So what is happening is this:
User[]
JSON object[]
JSON object[]
is transformed into a User's interface array (look at what is an interface in typescript) this.userList
as a User[]
but it is only a type assertion So using as
keyword is redundant in this case and completely useless.
A type assertion is only useful for autocompletion and other similar things that are elaborated at compile time. But it is not a real cast. So when you execute your code this.userList
is always a JSON Object[]
If you need real User objects you should do something like this:
_service.getUsers().then(i => {
this.userList = i.map(u => new User(u));
console.log(this.userList)
});
Obviously you should define a constructor into your User
class
EDIT
Looking at your Authors file I can see you are using an xml syntax that is converted into an array treated as Object. For this reason map operator fails. I have changed a bit your code
User
export class User {
userID : number;
FirstName : string;
userAge : string;
constructor()
constructor(u: User)
constructor(u?: User) {
this.userID = u && u.userID || -1;
this.FirstName = u && u.FirstName || '';
this.userAge = u && u.userAge || '';
}
clone(): User {
// TODO CLONE USER
return new User();
}
}
AppComponent
import { Component } from '@angular/core';
import { AppserviceService } from './appservice.service';
import { User } from './user';
import 'rxjs/add/operator/map';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
private userList: User[] = [];
constructor(private _service: AppserviceService) {
_service.getUsers().then(i => {
for (let c=0; c<10; c++) {
let u = new User(i[c]);
this.userList.push(u);
}
console.log('this.userList', this.userList);
});
}
}
Defining an interface with Typescript has absolutely no effect on generated Javascript code, since interfaces do not exist in Javascript. You can figure it out by playing with the Typescript playground . Interfaces are just something that help you (as a developer) and your team detecting errors at compilation time.
So the object you return from HTTP will always be as is, regardless of the interface you apply to it, because there is no such thing as interface or cast in Javascript.
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.