I am returning a custom response from Spring Boot API as below:
public static ResponseEntity<Object> generateResponse(String message, HttpStatus status, Object responseObj) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("Message", message);
map.put("Status", status.value());
map.put("Output", responseObj);
return new ResponseEntity<Object>(map,status);
}
which it will return: message, status and the output. So now I am wondering how could I make a custom response in Angular to receive all these three attributes. How should I replace the "???" with? I should be customizing the response base right?
public Get(): Observable<Book>{
return this.http.get< ???<Book> >(this.baseUrl).pipe(map(response => response.Output))
}
CodePudding user response:
You can use generics for this.
interface ApiResponse<T> {
message: string;
status: string;
output: T;
}
interface User {
id: number;
username: string;
}
interface BlogPost {
id: number;
title: string;
postedDate: Date;
}
Then you can have functions that return an ApiResponse
of some specific type. A plain typescript example:
const getUser = function(): ApiResponse<User> {
const response: ApiResponse<User> = {
message: 'test',
status: 'good',
output: {
id: 1,
username: 'test'
}
}
return response;
}
const getBlog = function(): ApiResponse<BlogPost> {
const response: ApiResponse<BlogPost> = {
message: 'test',
status: 'good',
output: {
id: 1,
title: 'Stuff!',
postedDate: new Date()
}
}
return response;
}
If you know the data in output
also shares some common attributes, you can even use generic constraints to further reduce any duplication in your typescript models.
interface ApiResponse<T extends DbModel> {
message: string;
status: string;
output: T;
}
interface DbModel {
id: number;
}
interface User extends DbModel {
username: string;
}
interface ThingThatDoesNotExtendDbModel {
someField: string;
}
//totally valid
const valid: ApiResponse<User> = { /* fields */};
/*
* Typescript compile error: Type 'ThingThatDoesNotExtendDbModel' does not satisfy the constraint
* 'DbModel'.
* Property 'id' is missing in type 'ThingThatDoesNotExtendDbModel' but
* required in type 'DbModel
*/
const invalid: ApiResponse<ThingThatDoesNotExtendDbModel> = { /*fields*/};