The following are a few examples, from basic to adding transformations after processing the request and / or error:
The main ones:
// Implementation code where T is the returned data shape function api<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error(response.statusText) } return response.json<T>() }) } // Consumer api<{ title: string; message: string }>('v1/posts/1') .then(({ title, message }) => { console.log(title, message) }) .catch(error => { /* show error message */ })
Data conversion:
Often, you may need to make some changes to the data before it is passed to the consumer, for example, by expanding the top-level data attribute. This is straightforward:
function api<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error(response.statusText) } return response.json<{ data: T }>() }) .then(data => { /* <-- data inferred as { data: T }*/ return data.data }) } // Consumer - consumer remains the same api<{ title: string; message: string }>('v1/posts/1') .then(({ title, message }) => { console.log(title, message) }) .catch(error => { })
Error processing:
I would say that you should not directly catch errors directly in this service, just letting it bubble, but if you need to, you can do the following:
function api<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error(response.statusText) } return response.json<{ data: T }>() }) .then(data => { return data.data }) .catch((error: Error) => { externalErrorLogging.error(error) throw error }) }
edit
There have been some changes since this answer was written. As mentioned in the comments, response.json<T> no longer valid. Not sure I could not find where it was removed.
For later releases you can do:
// Standard variation function api<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error(response.statusText) } return response.json() as Promise<T> }) } // For the "unwrapping" variation function api<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error(response.statusText) } return response.json() as Promise<{ data: T }> }) .then(data => { return data.data }) }
source share