ionic/angular- How to use interfaces correctly?
Solution 1
Interfaces in Typescript only provide a description of the shape of an object. If an object is created in TypeScript, the compiler can reason about whether the object is compatible with the interface. At runtime interfaces are erased, so there will be no check as to whether an object is compatible with an interfaces. When you make a request using post<T>
you are basically telling the compiler that the shape of the object you expect as a response if T
but no checking will be performed to ensure this.
You can have as many interfaces as you like in a file, and you can export them from that file an import them in another file just like you would a class or function. How you organize your code is up to you.
If you want ensure an object is correctly implemented at runtime see here
Solution 2
As you mentioned interfaces in typescript is for just defining a contract. So in your example it is just that you are expecting a log in response from the server with the properties you have mentioned in the interface. There is no constraint like in the interface we should mention all the properties returning in the JSON response. You can even add more properties in the interface if you want which is not present in the JSON response. So in your specific example by making use of interfaces you can get to know what is the specification of an API when you check the code in future. So below will be my implementation
I will create a new file called ILoginRequest.ts and declare interface called ILoginRequest
export interface ILoginRequest {
email:string;
password:string;
}
And use that interface as the type of the requestData input parameter in provider class
login(reqData:ILoginRequest ): Observable<LoginResponse[]> {
return this.http.post<LoginResponse[]>('localhost:3000/api/login', reqData);
}
So if we use the login function in the provider class anywhere else in the project we know what should be the input that need to given to the login method and what is the expected result from that function.
And in the calling page will assign the output from the api in loginResponse variable which is interface LoginResponse type. so where ever we use this variable in the class we know what all are the properties we can use and we get intelliSense support in IDE
export class LoginPage {
private loginResponse : LoginResponse;
constructor(private loginService: LoginServicesProvider) {
}
onSubmit() {
let reqParams = {
email: '[email protected]',
password: 'password',
};
this.loginService.login(reqParams).subscribe((res:LoginResponse) => {
console.log('success');
this.loginResponse = res;
});
} }
For more detailed information about the interface usage in typescript you can check this link.
About where to keep the interface, according to me it is just developers preference, you can create separate folder called interfaces in 'app' directory and create new file for each interfaces.
version 2
A software professional with 3.8 years of diverse experience in Software Development.
Updated on June 22, 2022Comments
-
version 2 almost 2 years
I'm pretty new to angular/ionic app development. I read the following somewhere
Interfaces are only at compile time. This allows only you to check that the expected data received follows a particular structure.
I'm making an ionic app and the API services returns some data back to user. Let's say it's a login function and the API service returns data for that.
I made a provider in Ionic from where HTTP calls are made to API using HTTPClient.
//Provider import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; interface LoginResponse { success: boolean; message: string; token: string; userId: number; } @Injectable() export class LoginServicesProvider { constructor(public http: HttpClient) { } login(reqData): Observable<LoginResponse[]> { return this.http.post<LoginResponse[]>('localhost:3000/api/login', reqData); } }
As you can see, I created an interface called LoginResponse
And the code for the Login component is as follows:
//Component import { LoginServicesProvider } from './../../providers/login-services/login-services'; import { Component } from '@angular/core'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'page-login-page', templateUrl: 'login-page.html', }) export class LoginPage { constructor(private loginService: LoginServicesProvider) { } onSubmit() { let reqParams = { email: '[email protected]', password: 'password', }; this.loginService.login(reqParams).subscribe(res => { console.log('success'); }); } }
For this example, I just print a message to console.
Now comes my questions
1) Like mentioned in the earlier statement, is my LoginResponse interface checking the data received? If not, how/where I should implement that check- in provider or component?
2) If I have multiple interfaces inside a single provider, let say, one for login data and other for user profile data or something, where should I place it? Can I keep it in a separate file and export it? I didn't see any ionic commands to create interfaces
Thanks! I don't wanna start my career from mistakes. That's why I thought of posting this.
-
mehany about 6 yearsI ld also add, It is also a great way to communicate with other developers on your project ( or even yourself 10 months later ) the shape of objects