When processing JSON responses in TypeScript, how do you safely check if a variable is an array and is not empty?
Let's say we get a response from an API (in this example, it's Kontent API):
const blogPosts: BlogPost[] = (await deliveryClient
.items<BlogPost>()
.type("blog_post")
.toPromise())?.data?.items
We expect that response to be an array of BlogPost
objects. Also, note the ?.
notation that allows us to unwind the response and select just the data we need. If the response doesn't have the expected format, we will get null
instead of undefined
error.
Therefore, we first need to check if the response is a defined array:
if (!Array.isArray(blogPosts)) {
throw new Error("Response has a wrong format")
}
The Array.isArray
function will catch all possible values:
// all these calls return false
Array.isArray(undefined)
Array.isArray(null)
Array.isArray({})
// DON'T DO THIS
// as there is no need for checking the variable separately
if (blogPosts && Array.isArray(blogPosts)) { }
// DO THIS
// Array.isArray() is doing the null and
// undefined check automatically
if (Array.isArray(blogPosts)){ }
Note: Check MDN Web Docs for more information.
Then, we check if the array contains any items via .length
property:
if (blogPosts.length == 0) {
throw new Error("Response contains no items")
}
And that's it. 💪
The full code looks like this:
const blogPosts: BlogPost[] = (await deliveryClient
.items<BlogPost>()
.type("blog_post")
.toPromise())?.data?.items
if (!Array.isArray(blogPosts) || blogPosts.length == 0){
throw new Error("No data")
}
// all good here
console.log(blogPosts)
You can also wrap the code in try/catch
block to make sure you also catch errors from network communication.
If you need any help with processing your Kontent data, join our Discord! 😎
Top comments (4)
Checking the array length in the if condition could be shortened to just
!blogPost.length
which will evaluate to true if the array is empty since 0 is falsy and gets inverted and coerced into a boolean.True, thanks for the comment! :-)
Typescript is not relevant to this at all
Actually, it is. The API response is typed, so in case you get different type of data, it won't get mapped to the type and the items array will be empty which in the end helps you handle the problem.
However, the Array.isArray will work in pure JS too.