Home > Mobile >  How to create a custom response base in Angular HTTP service?
How to create a custom response base in Angular HTTP service?

Time:02-11

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*/};
  • Related