DEV Community

Cover image for Building a WikiPedia Search Engine App with JS
Ishan Sharma
Ishan Sharma

Posted on • Originally published at blog.ishandeveloper.com

Building a WikiPedia Search Engine App with JS

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 :

Wiki-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.

<a href="" class="icon random-ico">
  <i class="fas fa-random"></i>
</a>
Enter fullscreen mode Exit fullscreen mode

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.

<a
  href="https://en.wikipedia.org/wiki/Special:Random"
  target="_blank"
  rel="noopener noreferrer"
  class="icon random-ico"
>
  <i class="fas fa-random"></i>
</a>
Enter fullscreen mode Exit fullscreen mode

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.

// Grab a reference to form element and store it
const form = document.querySelector(".search-form");
// Add an event listener to form submit event
form.addEventListener("submit", handleSubmit);
Enter fullscreen mode Exit fullscreen mode

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.

function handleSubmit(e) {
  e.preventDefault();
}
Enter fullscreen mode Exit fullscreen mode

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.

function handleSubmit(e) {
  e.preventDefault();
  let query = document.querySelector(".search-input").value;
  query = query.trim();
  console.log(query);
}
Enter fullscreen mode Exit fullscreen mode

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.

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

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 :

function handleSubmit(e) {
  e.preventDefault();
  let query = document.querySelector(".search-input").value;
  query = query.trim();
  getResults(query);
}
Enter fullscreen mode Exit fullscreen mode

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.

function getResults(query) {
  const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;

  fetch(url)
    .then((res) => res.json())
    .then((data) => console.log(data))
    .catch((e) => console.log(`ERROR : ${e}`));
}
Enter fullscreen mode Exit fullscreen mode

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.

function getResults(query) {
  const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;

  fetch(url)
    .then((res) => res.json())
    .then((data) => {
      putResults(data.query.search);
    })
    .catch((e) => console.log(`ERROR : ${e}`));
}
Enter fullscreen mode Exit fullscreen mode

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

function putResults(sResults) {
  // Refer to `.results` section
  const searchResults = document.querySelector(".results");
  searchResults.innerHTML = "";
  // Loop over each result
  sResults.forEach((result) => {
    //Generate a wikipedia page url for each result
    const url = encodeURI(`https://en.wikipedia.org/wiki/${result.title}`);

    //Insert a result item as a child one by one into the parent conainter
    searchResults.insertAdjacentHTML(
      "beforeend",
      `<div class="result">
      <h3 class="result-title">
        <a href="${url}" target="_blank" rel="noopener">${result.title}</a>
      </h3>
      <span class="result-snippet">${result.snippet}</span><br>
      <a href="${url}" class="result-link" target="_blank" rel="noopener">${url}</a>
    </div>`
    );
  });
}
Enter fullscreen mode Exit fullscreen mode

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.

const form = document.querySelector(".search-form");
form.addEventListener("submit", handleSubmit);

function handleSubmit(e) {
  e.preventDefault();
  let query = document.querySelector(".search-input").value;
  query = query.trim();
  getResults(query);
}

function getResults(query) {
  const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&origin=*&srlimit=25&utf8=&format=json&srsearch=${query}`;

  fetch(url)
    .then((res) => res.json())
    .then((data) => {
      putResults(data.query.search);
    })
    .catch((e) => console.log(`ERROR : ${e}`));
}

function putResults(sResults) {
  const searchResults = document.querySelector(".results");
  searchResults.innerHTML = "";
  sResults.forEach((result) => {
    const url = encodeURI(`https://en.wikipedia.org/wiki/${result.title}`);

    searchResults.insertAdjacentHTML(
      "beforeend",
      `<div class="result">
      <h3 class="result-title">
        <a href="${url}" target="_blank" rel="noopener">${result.title}</a>
      </h3>
      <span class="result-snippet">${result.snippet}</span><br>
      <a href="${url}" class="result-link" target="_blank" rel="noopener">${url}</a>
    </div>`
    );
  });
}
Enter fullscreen mode Exit fullscreen mode

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.

Originally posted on my personal blog

If you'd like to see more quick tutorials such as this, do let me know in the discussions below!

Top comments (0)