5

I have a function that calls a rest api like this:

getProducts(category: string): Observable<IProduct[]> {
    let url = `/rest/getproducts?category=${category}`;
    return this._http.get<IProduct[]>(url);
  }

The response from the service looks like this:

[
  {
    "ProductId": 1,
    "CategoryType": "XC",
    "Name": "Prod A"
  },
  {
    "ProductId": 2,
    "CategoryType": "XY",
    "Name": "Prod B"
  },
]

My model looks like this:

export interface IProduct {
    id: string;
    type: string;
    name: string;
}

Is there a way to map the response to my model in an easy way? Should I use the map function? I know I could change the model to suite the response, but I would rather like to squeeze the response into my model (the example is simplified).

1
  • 1
    If you need to change the name of the properties you will need to do the mapping manually. Libraries that can do this probably exist as well :) Commented Jan 26, 2019 at 11:13

2 Answers 2

6

The simplest solution would be to use an interface that is the shape of the actual data from the server. Less headache, no mapping, less maintenance.

Even if you want to do some mapping it would still be a good idea to have an interface for the server object, so mapping can be done safely:

interface IServerProduct {
    "ProductId": number;
    "CategoryType": string;
    "Name": string;
}

export interface IProduct {
    id: string;
    type: string;
    name: string;
}

getProducts(category: string): Observable<IProduct[]> {
    let url = `/rest/getproducts?category=${category}`;
    return this._http.get<IServerProduct[]>(url).pipe(
        map(o => o.map((sp): IProduct => ({ // IProduct specified here ensures we get excess property checks
            id: sp.ProductId + '', // number in server interface, map to string 
            name: sp.Name,
            type: sp.CategoryType,
            typeMisaken: sp.CategoryType, // error here
        })))
    );
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the example. I get an error though: error TS2552: Cannot find name 'map'. Did you mean 'Map'?
@Jojje there are two map calls, one is the array map which should be there, the other is the rxjs map. You need to import it from rx operators for this to work. What version of angular are you using?
im using Angular 5
@Jojje this should be the import, I currently don't have 5 available, but on 7 it's import { map } from 'rxjs/operators';
3

Your interface should look like the below, if you do not want to do any changes to code, you could check it here json2ts

declare module namespace {
    export interface IProduct {
        ProductId: number;
        CategoryType: string;
        Name: string;
    }
}

otherwise you could use the array.map function and generate your array on own.

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.