Render Prettified API JSON Response with an API Tester in React.js
Create a simple tool in React.js that allows you to visualize the structure of values returned by an API directly on a webpage with proper indentation and formatting.
Oct 1, 2020 • 7 Minute Read
Introduction
As a frontend developer, you'll often find yourself debugging values returned from an API in JSON format. In most cases, these return values are structured into complex nested objects of information. It's best to visualize the structure of the values being returned by an API directly in the webpage itself with proper indentation and formatting. In this guide, you will create a simple tool in React.js that allows you to do just that.
Setup
First, create a React.js component called APITester that initially looks like the following:
import React from 'react';
import $ from 'jquery';
export default class APITester extends React.Component {
constructor(props) {
super(props);
this.state = {
jsonData: {},
apiEndpoint: ""
}
}
render() {
return (
<div>
<pre>
{this.state.jsonData}
</pre>
<hr/>
<input
type="text"
/>
<button>
Fetch
</button>
</div>
);
}
}
There are two main state variables to maintain:
- jsonData: Used to store the response of the endpoint
- apiEndpoint: The API endpoint that the user will specify
User Input of API Endpoint
Next, fill in the functionality where the user will input the API endpoint in the input element. Every change will update the apiEndpoint state value.
First, create an event handler to be triggered on every modification of the input element:
handleEndpointChanged(event) {
this.setState({
apiEndpoint: event.target.value;
});
}
All this function is doing is updating the value of the state property apiEndpoint from event.target, which points to the input element this function refers to.
Attach the event handler to the input element's onChange attribute:
<input
type="text"
onChange={this.handleEndpointChanged.bind(this)}
/>
Fetching Data from an Endpoint
Next, create the event handler every time the button is clicked:
handleButtonClicked() {
var context = this;
$.ajax({
url: context.state.apiEndpoint,
dataType: "json",
method: "GET",
success: function(response) {
context.setState({
jsonData: response
});
}
});
}
This function fetches data from the endpoint as specified by the user, which in turn updates to the value apiEndpoint. It's expected that the return value will be of dataType: "json". On a successful call, the state property jsonData will have to be updated to the value of response, which contains the actual return value of the API endpoint apiEndpoint. Notice also that the function uses the variable context to refer to this, which is an instance of the component itself. This is necessary so you can still refer to the setState() method from within the success function. This can also be seen when assigning the value of url in the ajax call to context.state.apiEndpoint.
Next, attach the event handler to the onClick attribute of the button:
<button
onClick={this.handleButtonClicked.bind(this)}
>
Fetch
</button>
Once the button is clicked, the function handleButtonClicked will fire and, together with the ajax call, set the value for jsonData to be displayed in a prettified format (that is, with proper indentation, quotes, and nesting of objects).
Rendering the Prettified Version
On every trigger of setState, the render() function will be invoked, thus updating the expected interface of this component. To make sure that the JSON data displayed follows the proper format, there are two requirements:
- Make sure to format the JSON with appropriate escape characters for tabs and nested objects.
- Render the formatted JSON to a <pre> tag to retain its formatting on the web.
Your render() code should look something like this:
render() {
return (
<div>
<pre>
{JSON.stringify(this.state.jsonData, undefined 2)}
</pre>
<hr/>
<input
type="text"
onChange={this.handleEndpointChanged.bind(this)}
/>
<button
onClick={this.handleButtonClicked.bind(this)}
>
Fetch
</button>
</div>
);
}
You have to invoke the function JSON.stringify(someJsonData, undefined 2) to insert the necessary escape characters to format the object properly. Next, make sure that the resulting value after JSON.stringify is rendered between <pre> tags. This will allow the page to retain escape characters for proper formatting of the display, thus creating the prettifying effect.
Overall Code
import React from 'react';
import $ from 'jquery';
export default class APITester extends React.Component {
constructor(props) {
super(props);
this.state = {
jsonData: {},
apiEndpoint: ""
}
}
handleEndpointChanged(event) {
this.setState({
apiEndpoint: event.target.value
});
}
handleButtonClicked() {
var context = this;
$.ajax({
url: context.state.apiEndpoint,
dataType: "json",
method: "GET",
success: function(response) {
context.setState({
jsonData: response
});
}
});
}
render() {
return (
<div>
<pre>
{JSON.stringify(this.state.jsonData, undefined, 2)}
</pre>
<hr/>
<input
type="text"
onChange={this.handleEndpointChanged.bind(this)}
/>
<button
onClick={this.handleButtonClicked.bind(this)}
>
Fetch
</button>
</div>
);
}
}
Try it out by entering https://api.coindesk.com/v1/bpi/currentprice.json into the input element and hitting Fetch. It should return data relating to Bitcoin prices and render it with proper formatting on the webpage.
Conclusion
In this guide, you created a component that accepts a URL endpoint from the user representing an API that is expected to return JSON data. To examine the return value, the JSON response has to be first cleaned as a string with appropriate formatting using the JSON.stringify() function. When rendering to HTML, in order to retain the escape characters from the stringified JSON, the value has to be within <pre> tags. This way, the rendered data is much more presentable to the user for further analysis of the response.
Try it yourself, and try to extend the component to include the following:
- Differentiation between a GET and a POST
- Additional parameters with the request (also provided by the user)
- Error handling (in case the API endpoint does not return data type JSON)