Pulling data from REST APIs is a very common programming pattern. Using this data to render charts is equally as common.
I figured we (ZingChart) should write a tutorial on how exactly to do this since a lot of our users are probably doing this for their own web applications.
REST APIs are basically an exposed dataset (usually in JSON) that lives at a certain URL and is available to access programmatically through HTTP requests.
Disclaimer, this tutorial will be done in vanilla JavaScript.
I have chosen the Star Wars REST API as the REST endpoint we will be retrieving data from. I just chose it because we don't need authentication & it returns JSON data that is easy to work with.
Table Of Contents
If you don't want to read the tutorial, you can just see the full code (with comments) here.
AJAX Request
AJAX stands for asynchronous JavaScript and XML. Ajax is a set of strategies to make HTTP requests (GET, POST, PUT, DELETE) asynchronously. In this case, asynchronously means we don't have to reload our page every time we make an HTTP request. An AJAX request consists of 5 steps:
-
Creating a new HTTP request.
-
Loading the request.
-
Working with response data.
-
Opening the request.
-
Sending the request.
Creating A New HTTP Request
To initialize an AJAX request, we have to create a new instance and store it in a variable like so:
var xhr = new XMLHttpRequest();
Storing it in a variable allows us to use other AJAX methods on it later. I call it 'xhr' because that is a quick abbreviation I can remember; however you can call if whatever you like.
Loading The Request
The next step in our AJAX process will be to add an event listener to our request. Our event listener will be responding to a load
event that will fire once our request has loaded. This will be followed by a callback function.
The callback function in our event listener will operate in an if statement flow. If we receive a 200
status (which means ok) from the API endpoint, then we do something.
The entire sequence will look like this:
xhr.addEventListener('load', function() {
if (this.status == 200) {
// do something
}
});
Working With Response
Every AJAX request will send us back data. The tricky part is making sure we can work with this data in the way we want. There are going to be 4 steps in our process to receive data we can work with from this response:
-
Parsing the response to JSON and storing it in variables.
-
Creating empty arrays we can push our desired data into.
-
Looping through the response and pushing values we want to extract into our empty array.
-
Converting array values into workable data.
*Each of these steps will be executed within the if statement inside of our event listener.
Parsing The Response
Each response returns back a string of data. We want a JSON object so we can loop through these values. We can convert the response string into JSON using the JSON.parse()
method. We can store this in a variable called response
so we can work with this later like so:
var response = JSON.parse(this.responseText);
Now we have an array of objects stored in a variable. You can console.log(response);
to see the full array.
Within this array, there is one specific object we want to work with called results
. This object contains Star Wars characters and information about them. We are going to save this object in a variable so we can loop through in the next steps.
We can access this object using JSON dot notation on our existing response
variable. We are going to save it in a variable called characters
. It will look like this:
var characters = response.results;
Creating Empty Arrays
Next we will need to create a variable to hold an empty array. We will call this characterInfo
. When we loop through our object later, we can push values into this array. Check it out below:
var characterInfo = [];
*We can place array of arrays directly into ZingChart and render a chart with both x-axis and y-axis values. It's pretty useful.
Looping Through The Response
Since our character
variable will be stored in an array of objects, we can use the forEach
method to loop through this.
The forEach
method takes in a callback function that will take in a character
as a parameter. The character parameter serves the same purpose characters[i]
would inside of a for loop. It stands for the object it is currently looping through. We can use JSON dot notation to access any piece of the object we desire during the loop.
There are two pieces of data we are going to pull from each object; name
& height
. This is where our empty array from earlier will come into play. In each object we loop through, we can use the array.push()
method inside of our callback function to push values to the end of our empty characterInfo
array.
We can push values in array format so we can have an array of arrays containing character name and height. These values will be returned as string values, which is fine for the name attribute. However, we can use the parseInt()
method to typecast each height value into a number from a string.
Altogether, our code will look like this:
xhr.addEventListener('load', function() {
if (this.status == 200) {
var response =
JSON.parse(this.responseText);
var characters = response.results;
var characterData = [];
characters.forEach(function(character) {
characterData.push([character.name,
parseInt(character.height)]);
});
});
Opening The Request
The last two steps of this AJAX request are what actually makes this thing go. First, is the open method. This opens our request. This request is going to be a GET request. Which is the HTTP part of this XMLHttpRequest();
method.
This GET request is what actually reaches this API endpoint and retrieves data. I'll show you what it looks like and then we will dissect this.
xhr.open('GET', 'https://swapi.dev/api/people/');
With .open
we are opening this request to the URL specified which is https://swapi.dev/api/people/
. This will return an array of objects that contains Star Wars characters and some additional data about them. REST APIs generally have an API URL you can reach to grab data. If you are curious, check out the Star Wars API docs to see the different sets of data you can retrieve.
REST APIs pretty much let you dictate what data you want by manipulating the URL. Play around with the Star Wars API in your own demo later to see exactly what you can get.
Sending The Request
The last step is arguably the most important piece of your AJAX request. If you don't do it, none of this tutorial will function. We have to use the .send()
method on our xhr
variable in order to actually send the request like so:
xhr.send();
Now that we have the skeleton of our AJAX request, we can work with the response we get sent back from the Star Wars REST API endpoint.
Rendering A Chart
Rendering a chart consists of four steps:
-
HTML: Creating a
<div>
with a unique id. -
CSS: Giving this
<div>
a height and width. -
JS: Creating a chart configuration variable.
-
JS: Using the
zingchart.render({});
method to render the chart.
HTML
In order to render out a chart, we will need a chart container. We can use a <div>
to do this. We will also need to give this <div>
a unique ID like this:
<div id="chartOne"></div>
I use the numbered chart method because it's easy to find in the code if we need to reference later.
CSS
We will use that unique ID in our CSS to declare a height & width:
#chartOne {
height: 200px;
width: 200px;
}
If we fail to declare a height & width, our chart will not render.
Chart Configuration Variable
You can name this demo whatever makes sense to you within your application. I chose to name it 'chartOneData' as we can easily tie this back to our 'chartOne' ID.
There are really only two important aspects of this variable:
-
Declaring a chart type (we are using bar in this example).
-
Adding values to our chart.
*All of our chart information will be placed in our event listener callback function.
Declaring A Chart Type
ZingChart has a declarable syntax, so choosing a chart type is as easy as declaring a key value pair like this:
var chartOneData = {
type: 'bar'
};
Adding Values To The Chart
Adding values to our chart is done in similar fashion to declaring a chart type. This time we will add a key value pair with a nested key value pair. series
will take an object called values.
Within this values object, we can pass in the array we pushed data into. This holds all of our character information. It will look like this:
var chartOneData = {
type: 'bar',
series: [
{
values: characterInfo
}
]
}
Rendering Our Chart
Rendering our chart is pretty simple as well. There is a built-in render method we can use and all you have to do is pass in a few key value pairs which are:
-
id
: this is the id we passed into our<div>
element. -
data
: this will be the name of the chart variable we declared previously. -
height
: this will be a value of '100%' to fill our container. -
width
: this will also be a value of '100%' to fill our container.
zingchart.render({
id: 'chartOne',
data: chartOneData,
height: '100%',
width: '100%'
})
Now that we have this going, we should have a full chart rendered that has successfully pulled data from a REST API. Nice!