2

I have a generic API service in my app that makes requests like this to the backend:

post<T>(url: string, jsonObject: object): Observable<T> {

    return this.http.post<T>(url, JSON.stringify(jsonObject));

}

I use that method like this from my components and try to cast the response as a specific model:

this.apiService.post<SomeSpecificModel>('some/path/here', this.usernameForm.value)
                                        .subscribe(
                                            res => {
                                                console.warn(res);
                                            },
                                            () => {
                                                console.warn("error");
                                            }
                                        );

My problem is that the API returns content like this:

{
    code: some-string,
    type: some-number,
    data: []
}

And the data property is where the entity is that I want to cast with my model in Angular.

I would still like to have access to both code and data properties in my component, but I am not sure how to accomplish that.

Can I make a base model that mimics the response from the API and has a generic array property? Something like this:

export class BaseModel<T> {
    code: string;
    type: number;
    data: Array<T>;
}

And then cast like this?

this.apiService.post<BaseModel<SomeSpecificModel>>(...

I tried that and I don't get any build errors, but the properties on SomeSpecificModel is not mapped.

4
  • Can you show what your object looks like when doing this? e.g. when logging to the console Commented Apr 10, 2018 at 4:48
  • Are you sure your data is an array when coming from the server? Commented Apr 10, 2018 at 4:53
  • let me know it you need more help Commented Apr 10, 2018 at 6:13
  • Define both BaseModel and SomeSpecificModel as interfaces and let me know if it makes a difference Commented Apr 10, 2018 at 12:03

1 Answer 1

2

Try something lke this.

Your service code

  public fetchData<T>(resourcePath: string):Observable<ResourceData<T>> {
    return this.http.get<ResourceData<T>>(resourcePath);
  }

Your component code

this.yourService.fetchData<DropDownDataItem>('/your/path/')
      .map((response) => {
        return {
          count: response.count,
          items: response.data
        };
      });

Inteface

export interface DropDownDataItem {
  id: number;
  name: string;
}

export interface ResourceData<T> {
  data: T[];
  limit?: number;
  offset?: number;
  count: number;
}

Hope this helps

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.