Issue
I've been trying to learn ReactJS and TypeScript and have this question below:
export type CartItemType = {
id: number;
title: string;
price: number;
quantity: number; // This key is not available in API data
}
const getItems = async (): Promise<CartItemType[]> =>
await (await fetch('https://someapi.com/products')).json();
**API JSON is in this format:**
[{id:1, title: 'Large Shirt', price: 10.00},
{id:2, title: 'Medium Shirt', price: 8.00}
{id:3, title: 'Small Shirt', price: 5.00}
]
Even though, 'quantity' key isn't available in the api data, it doesn't throw any warning about 'quantity' key. I suppose it doesn't know what structure the api data is?
However, if I try to feed this data from a local array e.g.
function itemsData(): CartItemType[] {
return [
{ id: 10, title: "Jeans", price: 0.95},
{ id: 20, title: "Shirt", price: 2.10},
{ id: 30, title: "Trouser", price: 1.30},
]
}
const getItems = itemsData();
Then, it straightaway throws an error that 'quantity' is defined in the type and missing in this data in itemsData()
I need to add an additional key in this data array to compute some values (e.g. number of same products added in the cart)
How do I make it work similar to api data? I just need a way to fetch data locally as testing at the moment but eventually link back to api.
Solution
Typescript can only give you information on compile time. You cannot see the error in the console on your browser, because the browser does not understand Typescript. The code gets converted into JavaScript before it is read by the browser, and all the Typescript specific syntax get removed as a result.
When you define an API response as an interface in Typescript, you should only define it with the properties that are expected from the API
If some properties might be optional and not always returned from the API, you can make it an optional property by adding a question mark behind it, like so.
export interface CartItemType {
id: number;
title: string;
price: number;
quantity?: number;
}
But what you might want to do instead, is to only define types that correspond to your code, and not to the API response.
Instead, build a function to normalize the data you get from the API, like so:
const apiToJSON = (response: unknown): CartItemType => {
return {
id: response['id'] || null,
title: response['title'] || null,
price: response['price'] || null,
quantity: response['quantity'] || null,
};
}
With this, you can define a default value for any value that might be missing from the API, and the return of this function should correspond to the CartItemType
Answered By - Einar Ólafsson
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.