Reddit is a news aggregation, communication, and discussion application. If you want to get more information about a particular topic or have a question, Reddit is the place to be. The data on Reddit are provided to the public through both the website and its API.
Learning how to use the Reddit API is beneficial if you want to integrate Reddit communications into your application or if you just want to use certain data on Reddit.
The aim of this tutorial is to show how you can extract article content from Reddit using the Reddit API without a Reddit account. I will show how the results can be limited to the range of 5 to 100 results. We will also build a feature to sort the articles by either relevance or date (latest). Extraction of the data will be done with JavaScript, and then it will be bundled with Parcel so that we can view the data in a browser.
You can find the code used in this article on GitHub.
Prerequisites
To follow along with this tutorial, you should have the following:
- Basic knowledge of APIs.
- Basic knowledge of JavaScript.
- npm installed.
How to set up Parcel
Parcel is a JavaScript bundler for Web applications with zero configuration and is straightforward to set up. It packages all the application files in a dist folder
, so the application can be run.
First, create a new folder for the Reddit API example application:
mkdir reddit-example
To get started, we will install Parcel. First, create a new folder for the project and navigate to it on your terminal. You can now run the following command in the project folder to install Parcel with npm
:
npm install --save-dev parcel
Parcel also starts the development server on the terminal, which you can do by running the following command in the terminal:
npx parcel index.html
This will fail for now because index.html
doesn't exist yet. We'll create it next.
Building the application
First, create index.html
and index.js
files in the folder you created for this Reddit API tutorial.
To show all the features that were mentioned in the introduction of this tutorial, we will build an app that uses the functionality. This app is built using HTML, Bootstrap, and JavaScript.
Let’s first quickly build out the HTML for the example webpage. Paste the following in index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<!-- <link rel="stylesheet" href="style.css"> -->
<title>Search Reddit</title>
</head>
<body>
<nav class="navbar navbar-dark bg-primary mb-3">
<div class="container">
<span class="navbar-brand">Search Article</span>
</div>
</nav>
<div id="search-container" class="container">
<div id="search" class="card card-body bg-light mb-2">
<h4>Search Reddit</h4>
<form id="search-form">
<!-- this form contains the search box -->
<div class="form-group">
<input type="text" id="search-input" class="form-control mb-3" placeholder="Search Term...">
</div>
<div class="form-check form-check-inline">
Sort By:
<!-- here we used the radio to input type to select and we made sortby be the default-->
<input class="form-check-input ml-2" type="radio" name="sortby" value="relevance" checked>
<label class="form-check-label">
Relevance
</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sortby" value="new">
<label class="form-check-label">
Latest
</label>
</div>
<h5 class="mt-2">Limit: </h5>
<div class="form-group">
<!-- 25 is selected as default for the number of result to be displayed -->
<select name="limit" id="limit" class="form-control">
<option value="5">5</option>
<option value="10">10</option>
<option value="25" selected>25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
<!-- this is the button to search -->
<button type="submit" class="btn btn-dark btn-block mt-4">Search</button>
</form>
<!-- with the id below we will use it to diplay the result in javascript -->
</div>
<div id="results"></div>
</div>
<script src="./index.js" type="module"></script>
</body>
</html>
Since we are focusing on the Reddit JavaScript integration, we'll skip over the explanation of this HTML and go straight to the JavaScript work.
Writing JavaScript for the search page
We have to get the id
s for the search button and input form and then add an event listener so that when you submit the form, a function is triggered to get the “sortby” input value and the “limit”.
To make sure we cannot submit an empty search box, we will add an alert message. This will be done using an if
statement.
You can get this working by pasting the following code into your index.js
file:
const searchForm = document.getElementById("search-form");
const searchInput = document.getElementById("search-input");
// Form event listener
searchForm.addEventListener("submit", (e) => {
e.preventDefault();
// get search term
const searchTerm = searchInput.value;
//get sort
const sortBy = document.querySelector('input[name="sortby"]:checked').value;
// get limit
const searchLimit = document.getElementById("limit").value;
// check input if empty
if (searchTerm === "") {
showMessage("Please add a search term", "alert-danger");
}
// to clear input after search
searchInput.value = "";
});
Fetching from the Reddit data API
To fetch Reddit data from the API, we will create another JavaScript file at the root of your project named redditapi.js
. In this file, we will create a module object and make the request to fetch the API, and export the file to index.js
. To get the right Reddit data as a JSON object, you need to use the search endpoint. In the Reddit API docs, you will find basic information about the search endpoint. The query string parameters will be added dynamically from the HTML form. There's no need for an access token or to set the user agent, though other API requests will require different parameters like a redirect URI.
To get this working, paste the following code into the file below:
export default {
search: function (searchTerm, searchLimit, sortBy) {
// fetch api of reddit
return (
fetch(
`http://www.reddit.com/search.json?q=${searchTerm}&sort=${sortBy}&limit=${searchLimit}`
)
.then((res) => res.json())
.then((data) => data.data.children.map((data) => data.data))
// to get error
.catch((err) => console.log(err))
);
},
};
Now, we have to import the module to the index.js
file by adding this import statement to the top of index.js
:
import reddit from './redditapi';
Note that reddit
in the inline code above is a variable that we will use to call the search function.
To display the Reddit data, we will output to the UI using the Bootstrap card. We will loop through all the results and create a card for each one. The following code will handle that.
Replace the event listener (it starts with searchFrom.addEventListener
) with this:
searchForm.addEventListener("submit", (e) => {
e.preventDefault();
// get search term
const searchTerm = searchInput.value;
//get sort
const sortBy = document.querySelector('input[name="sortby"]:checked').value;
// get limit
const searchLimit = document.getElementById("limit").value;
// check input if empty
if (searchTerm === "") {
showMessage("Please add a search term", "alert-danger");
}
// to clear input after search
searchInput.value = "";
reddit.search(searchTerm, searchLimit, sortBy).then((results) => {
let output = '<div class="card-columns">';
// loop through each post in the JSON response
results.forEach((post) => {
// A div for each new one
output += `<div class="card">
<div class="card-body">
<h5 class="card-title">${post.title}</h5>
<p class="card-text">${truncateText(post.selftext, 100)}</p>
<a href="${post.url}" target="_blank" class="btn btn-dark">Read More</a>
</div>
</div>`;
});
output += "</div>";
document.getElementById("results").innerHTML = output;
});
});
As you can see, we have appended the result to the DOM where the id=results
are located in the HTML file. In the code above, I also used the function truncateText
on the selftext
(which contains the post details) to shorten the post.
Below is the implementation of that function. Paste the following code at the end of your index.js
:
// truncate text
function truncateText(text, limit) {
const shortened = text.indexOf("", limit);
if (shortened == -1) return text;
return text.substring(0, shortened);
}
You can now run the Parcel server by running the following command:
npx parcel index.html
You will be provided with a URL (http://localhost:1234
) that can be used to access your app in a browser.
From the image above, we can see that the application searched Reddit for the search term and organized the results in neat Bootstrap cards. The “Read More" buttons, when clicked, will open a new tab with the content of the search for one to read.
Mastering how to use the Reddit API
In this article, we have seen how the Parcel works and how to install it globally using npm
. We walked through how to use the Reddit API by building a real application that searches the Reddit API directly and fetches the data entered from the form. We also found a way to filter searched items based on relevance, the latest, and the number of results you want to receive.
If you're looking to expand the functionality of this example, consider implementing exception handling to make the app more resilient or even explore other endpoints to build even more features like showing user flair on posts. I would advise you to get familiar with the Reddit API documentation so that you will be able to implement more features of the API in your future projects.