Navigate back to the homepage

Building a Wikipedia Search Engine App with JS

Ishan Sharma
June 7th, 2020 · 4 min read

I honestly believe that the best way to learn any new technology, programming language, is by building something in that language and putting our knowledge to some practical use.

I receive plenty of messages and queries from some of my dearest friends and juniors asking how to start development, and how to put together the skills they’ve learnt to actually create something.

While, there are many tutorials on the internet, but most of them are not so beginner friendly, they tend to make a lot of assumptions on the reader’s part.

I hope to do my fair duty towards my friends and juniors by writing tutorials on this blog to help grasp several concepts in development and get some apps on their portfolio.

So, without further ado, Let’s Jump right, in!

What We’re Gonna Build

I will take you through how to build a Wikipedia Search App with JavaScript. This project was listed in one of the challenges at FreeCodeCamp.

You can actually view a live version of the finished project in your browser at,

wikisearch.ishandeveloper.com

This is the practical working of the app, from a user-perspective:

  1. User can search for Wikipedia articles in a search box and view the results in the app itself.
  2. User can visit a random Wikipedia article using the random button.

Pre-Requisites

Knowledge of basics of HTML, CSS & JavsScript is required as this tutorial is intended for beginners who want to learn how to create simple web apps using JavaScript.
If you’ve never built any app before, don’t worry! We’ll get through this, together!

If you get stuck at any point in this tutorial, you can always refer to the project source code available on github.

Let’s Get Started

I have already created a repository with the starter files for this project, you can download them, here or from the Github Repository.

These starter files contain the basic markups and stylings for this tutorial. We’re gonna concentrate only on seeing how the JavaScript works.

Just to ensure that we’re all on the same page, before we start

  1. Download the Starter Files, from above.
  2. Open the project in your preferred code editor (I prefer VSCode).
  3. Open index.html in your browser (or live-server, if you know that sort of thing).
  4. In your code editor, open ’main.js’ file.

In your browser, you should be able to see, a search bar 🔍 like this :

WikiSearch Search Bar

Once that’s done. Let’s proceed to add functionality to our app. For the sake of easiness, I’m actually splitting this section into three parts, each part targetting a different objective.

  1. Redirecting user to a random article.

  2. Sending/Recieving search query data from Wikipedia API .

  3. Displaying the search query results on our page.

Let’s start with the first one, as it is the easiest to implement.

1. Redirecting user to a random article.

Remember? One of the functionalities we wanted to add initially was, ‘User can visit a random Wikipedia article using the random button’.

It is fairly easy to do so. In the startup files, I have already created a button, which is actually just an icon enclosed within a link, which I styled to look like a button.

1<a href="" class="icon random-ico">
2 <i class="fas fa-random"></i>
3</a>

To achieve this, we can use :

  • `https://en.wikipedia.org/wiki/Special:Random`

This is a special link, you can try opening it in your browser and you’ll be redirected to a random wikipedia article each time. Here’s how it can be implemented.

1<a
2 href="https://en.wikipedia.org/wiki/Special:Random"
3 target="_blank"
4 rel="noopener noreferrer"
5 class="icon random-ico"
6>
7 <i class="fas fa-random"></i>
8</a>

Now, you should be able to click on the random button, which takes you to a random wikipedia article.Voila! Just like that, our first task is complete!

Here’s a quick breakdown of the above code,

  • href attribute refers to the url of the page we're redirecting to.
  • target="\_blank" helps to ensure that the link always opens in a new tab.
  • rel="noopener noreferrer" is actually here to help fix a security vulnerability with 'target=\_blank', you can read more on that, here.

2. Sending/Recieving search query data from Wikipedia API .

Okay, so the first task here would be to actually retrieve the data entered into the search bar by the user. Let’s do that.

1// Grab a reference to form element and store it
2const form = document.querySelector(".search-form");
3// Add an event listener to form submit event
4form.addEventListener("submit", handleSubmit);

Here’s a breakdown:

  • querySelector() : It returns the first Element within the document that matches the specified selector, more on MDN docs.
  • addEventListener : It takes two arguments: the DOM event we want to listen for and and the function that will run when the event is triggered (in this case, 'submit' is the DOM event & 'handleSubmit' is the function), more on MDN docs.

Now, let’s move ahead and create handleSubmit() function.

1function handleSubmit(e) {
2 e.preventDefault();
3}

Here’s a breakdown:

  • You may have noticed 'e' as the parameter which is the event that triggered the execution of the function.
  • e.preventDefault() : By default, the browser has a tendency to refresh the page, whenever a form is submitted. To prevent this, we're using 'preventDefault()' method, more on MDN docs.

Our page doesn’t reload on form submission, but our function doesn’t do anything, right? Let’s fix this.

1function handleSubmit(e) {
2 e.preventDefault();
3 let query = document.querySelector(".search-input").value;
4 query = query.trim();
5 console.log(query);
6}

You can press Ctrl+Shift+J / Cmd+Opt+J to open console in chrome and should see an output, once you submit a query in the search bar.

With this, almost half of the job for this step is done! Now, all we have to do is to send the search query to the Wikipedia API and fetch the results.

I have already specified the relevant URL parameters, that we’ll be using for this tutorial.

1https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=SEARCH_QUERY

I’ll break this down, quickly:

You can refer to this page for more details.

Moving on, we need to make an actual request to Wikipedia and retrieve the results from there. So, let’s replace ’console.log(query);’ with ’getResults(query);‘.

The handleSubmit function should now look like this :

1function handleSubmit(e) {
2 e.preventDefault();
3 let query = document.querySelector(".search-input").value;
4 query = query.trim();
5 getResults(query);
6}

Now, let’s create this getResults() function and fetch the search results. We’ll be using template literals to add user’s search query parameter into the API URL, mentioned above.

1function getResults(query) {
2 const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;
3
4 fetch(url)
5 .then((res) => res.json())
6 .then((data) => console.log(data))
7 .catch((e) => console.log(`ERROR : ${e}`));
8}

Let’s break this down:

  • Here we’re using back ticks (`) for storing the api url in a variable, for more on template literals, refer to MDN docs.
  • fetch() : This is an inbuilt method, it takes the url as a parameter specifies that we are expecting a JSON response from Wikipedia & returns a Promise Object. more on MDN docs
  • The first .then() expression returns another Promise so we call a second .then() on that to handle the JSON data and log it to the console.
  • .catch() : is used to catch any errors, that may occur, it'll log an error message to the console if something goes wrong.

Try typing into the input field and submit the form. The raw JSON data will be logged to the console. And with this, we have successfully completed Step 2.

3. Displaying the search query results on our page.

This is the final step of the tutorial, we have recieved the input, we have got the results, now all we need to do is to display those results.

If you take a closer look at the RAW JSON data, logged to the console in the previous step. You’ll see that the data object consists of several keys.

The key named ‘search’ is the only one useful to us for now. We can access it using data.query.search.

Now that we have the search results, let’s first modify the getResults function to display results.

1function getResults(query) {
2 const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;
3
4 fetch(url)
5 .then((res) => res.json())
6 .then((data) => {
7 putResults(data.query.search);
8 })
9 .catch((e) => console.log(`ERROR : ${e}`));
10}

Now, let’s create a new function’putResults()’ to which will recieve the search data and add display them on our web page.

1function putResults(sResults) {
2 // Refer to `.results` section
3 const searchResults = document.querySelector(".results");
4 searchResults.innerHTML = "";
5 // Loop over each result
6 sResults.forEach((result) => {
7 //Generate a wikipedia page url for each result
8 const url = encodeURI(`https://en.wikipedia.org/wiki/${result.title}`);
9
10 //Insert a result item as a child one by one into the parent conainter
11 searchResults.insertAdjacentHTML(
12 "beforeend",
13 `<div class="result">
14 <h3 class="result-title">
15 <a href="${url}" target="_blank" rel="noopener">${result.title}</a>
16 </h3>
17 <span class="result-snippet">${result.snippet}</span><br>
18 <a href="${url}" class="result-link" target="_blank" rel="noopener">${url}</a>
19 </div>`
20 );
21 });
22}

And that’s it! Is it? Wait! Don’t just leave yet. Let’s see what is actually happening in the code above.

Here’s a quick breakdown :

  • encodeURI() : Please note that URLs Cannot Contain Spaces. Therefore, this method is necessary as it helps to convert unformatted text (with whitespaces), into encoded text.
    • For example: If I pass a search query for ‘Linus Torvalds’ as a paramter, encodeURI function will return ‘Linus%20Torvalds’. For more, refer to MDN docs.
  • sResults.forEach() : This method is used to iterate over each item of an array, Please Note that instead of using array.forEach, we can also use array.map(). For more, refer to MDN docs.
  • insertAdjacentHTML : It takes two arguments: The position where we want to append the element and a string containing the HTML to insert on the page. For more info, refer to MDN docs.

Here’s The Complete Code

In case, you need it.

1const form = document.querySelector(".search-form");
2form.addEventListener("submit", handleSubmit);
3
4function handleSubmit(e) {
5 e.preventDefault();
6 let query = document.querySelector(".search-input").value;
7 query = query.trim();
8 getResults(query);
9}
10
11function getResults(query) {
12 const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;
13
14 fetch(url)
15 .then((res) => res.json())
16 .then((data) => {
17 putResults(data.query.search);
18 })
19 .catch((e) => console.log(`ERROR : ${e}`));
20}
21
22function putResults(sResults) {
23 const searchResults = document.querySelector(".results");
24 searchResults.innerHTML = "";
25 sResults.forEach((result) => {
26 const url = encodeURI(`https://en.wikipedia.org/wiki/${result.title}`);
27
28 searchResults.insertAdjacentHTML(
29 "beforeend",
30 `<div class="result">
31 <h3 class="result-title">
32 <a href="${url}" target="_blank" rel="noopener">${result.title}</a>
33 </h3>
34 <span class="result-snippet">${result.snippet}</span><br>
35 <a href="${url}" class="result-link" target="_blank" rel="noopener">${url}</a>
36 </div>`
37 );
38 });
39}

Here’s a Live Demo of the finished project 😉

With that, we’ve reached the end of this tutorial. I hope you enjoyed it 😄

This was just to give you a brief look into putting together everything you might’ve learnt about web development into an actual project.

If you want to improve this project,

Here are some ideas

  • Show a progress indicator while the request is processing.
  • Add search suggestions in the search bar, when the user is typing.
  • Display results on more than one page.

Join my mailing list and get notified about new blogs

Be the first to receive my latest content with the ability to opt-out at anytime. Of course, I promise that I won't spam your inbox or share your email with any third parties.

More articles from Ishan Sharma

2023 - Year In Review

A look back at the highs and lows of 2023, and the lessons I've learnt along the way

January 7th, 2024 · 9 min read

The Culinary Code - From bytes to bites

From novice to kitchen enthusiast – my culinary journey in Bangalore. Unexpected delights and flavorful discoveries

December 3rd, 2023 · 6 min read
© 2020–2024 Ishan Sharma
Link to $https://twitter.com/ishandeveloperLink to $https://github.com/ishandeveloperLink to $https://www.linkedin.com/in/ishandeveloperLink to $https://stackoverflow.com/users/13219775/ishandeveloperLink to $https://medium.com/@ishandeveloper