blog-How-to-build-a-Wikipedia-search-app-using-Javascript

How to build a Wikipedia search app using Javascript

Posted on:

GOAL:

Create a search app where the user enters a search text into the input text field. On clicking the search button, the app will display the Wikipedia search results with a title, a snippet of the article, and a link to the Wikipedia article. The user can click any of the results and go to the relevant Wikipedia page. We will be using some of the Wikipedia API to get the results onto our app.

Step 1: Create the HTML structure.

  • Create HTML for a form with a text input field and a button.
  • Create an empty div where the results of the search will be displayed.
  • Add id for the text field, form, and the empty div so we can use Javascript to hook to these elements.
  • Add some basic CSS to change the look and feel of the form elements from the default browser settings.

The HTML snippet

<form id="searchForm">
<input id="searchInput" type="text" autocomplete="off">
<button for="search">Search</button>
</form>
<div id="resultsList"></div>

The CSS snippet

#searchInput {
font-size: 30px;
width: 10em;
}
button {
background-color: #f8f5f1;
font-size: 30px;
padding-left: 15px;
padding-right: 15px;
text-transform: uppercase;
color:#443328;
font-weight:bold;
}

Step 2: Hook to the form’s submit event.

  • Hook on to the document’s form element.
  • Look out for the form element’s submit an event by using the ‘addEventListener’ method.
  • Prevent the default behavior of the submit event. Instead of the submit events default behavior- sending the data to the server, we want the web browser to handle things from the javascript.
  • Add a simple alert inside the ‘addEventListener’ method to test out the code.
Notes:
  • The ‘addEventListener’ method takes in two parameters- The event we want to listen to and the function that you want to run when the event happens.
  • Instead of using an anonymous function, we are using the arrow function as the second parameter.
  • The default behavior of a submit event is to send the data to the server. In this case, we don’t want that. We want the web browser to handle things from the Javascript instead. Hence we use a method called preventDefault.
  • The addEventListener passes a ton of information about the event to our function as a parameter. To access the information, we use a variable ‘e’ and call the method preventDefault to prevent the form’s default submit behavior.

The Javascript snippet

let searchForm = document.getElementById('searchForm');


searchForm.addEventListener('submit', (e)=> {
e.preventDefault();
alert('You Have Clicked The Search Button');
})

Step 3: Extract the form input and pass it to a function.

  • Hook on to the form’s input text field.
  • Get the value entered inside the text field.
  • Pass the user input text field value to a new function.
  • Inside the function, log out the input value to the console, to test out that we are accessing the correct information.

The Javascript snippet

let searchInput = document.getElementById('searchInput');
searchForm.addEventListener('submit', (e)=> {
e.preventDefault();
displaySearchResults(searchInput.value);
})
function displaySearchResults(x){
console.log(x);
}

Step 4: Sent a request to Wikipedia and get the response.

  • Our next step is to actually send the request to Wikipedia and handle the response from them, by using the Wikipedia API. We will be sending the request as a Wikipedia search query with a few required parameters.
  • A typical version of the search query is as shown: https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=&format=json&origin=*&srlimit=20&srsearch=USER_INPUT_SEARCH_TERM.
  • We replace the ‘USER_INPUT_SEARCH_TERM’ in the above search query with the variable that stores the input text we retrieved from the text field in Step 3 using a Temperate literal.
  • We then log the result to the console to test the complete search query string.

The Javascript snippet

let url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=&format=json&origin=*&srlimit=20&srsearch=${x}`;
console.log(url);
Notes:
  • There are two parts to the Wikipedia API.
  • The first part is the API Entry Point: ‘https://en.wikipedia.org/w/api.php’ – This is the URL where you make all your API calls. Hence it is the part common to all API calls.
  • Parameters: The rest of the URL are parameters. In the parameters, you specify what exactly you want from the API call.
  • The API Search Page lists all the parameters that can be used to create the GET Search query.
  • A few parameters to note are:
    1. action: There are many action parameters available in the Wikipedia API. action=query parameter is used to get information about a Wikipedia article. Another common action parameter is action=opensearch which is used to search Wikipedia.
    2. &srlimit=20 : How many pages of search results to return.
    3. &srsearch : The search text input by the user in the text field.
    4. &format=json : Makes sure the result is sent as a JSON object.
    5. &origin=* : Helps to get around the Cross-Origin Resource Sharing limitations. If you don’t add this parameter, you will run into the following error message on the console: Access to XMLHttpRequest at ‘https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=&format=json&srlimit=20&srsearch=javascript’ from origin ‘https://femkreations.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
      Cross-Origin Read Blocking (CORB) blocked cross-origin response https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info&inprop=url&utf8=&format=json&srlimit=20&srsearch=javascript with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
  • Temperate literals are enclosed between two back-ticks (“). On a MAC, you can find the back-tick key above the tab key.
  • Temperate literals can have placeholders in the text with the expression or variable you want to replace. These are indicated by the dollar sign and curly braces (${expression}).

Step 5: Get and write out the response object onto the console.

  • To send an AJAX request and fetch the data from the server, we will use a new browser built-in API called ‘fetch‘. The fetch API takes one mandatory argument- the path to the resource you want to fetch.
  • Fetch returns a promise which is like a placeholder for the response we’ll get from the asynchronous operation.
  • We’ll use the ‘.then’ method to handle the response object which represents the response of the asynchronous operation. The response object returned by a fetch() call contains all the information about the request and the response of the network request.
  • We then log out the response object onto the console.
  • We use the catch method of the promise to intercept any error occurring during the execution of the request and also after the processing done in the ‘then’ method.

The Javascript snippet

fetch(url)
.then(function(response) {
console.log(response);
});
.catch(function() {
console.log('An error occurred');
});
Notes:
  • The statusText is a property in the response object representing the status message of the response. If the request is successful, the status is OK.
  • The Status property is an integer number representing the HTTP response status.

Step 6: Extract the JSON from the response object.

  • To extract the JSON content from the response object, we’ll use the json() method.
  • This conversion method returns another ‘promise’. We can chain this promise with another ‘then’ call to get the data we wanted, in the format we wanted and display on the console.

The Javascript snippet

fetch(url)
.then(function(response) {
return(response.json());
})
.then(function(data){
console.log(data);
})
.catch(function () {
console.log('An error occurred');
});
Notes:
  • There are other methods to deal with different types of response data. If we’re requesting an XML file, then we’d call response.text. If we requesting an image, we’d call response.blob.

Step 7: Examine the contents of the JSON object.

  • The next few steps are to display the JSON data onto the web page. When we examine the contents of the JSON data that we logged into the console(from the previous step), we can see that the data object contains a couple of keys with different contents. The one key that is relevant for us is ‘search’ which is an array of objects nested inside the ‘query’ object. We can access this object using the dot notation – data.query.search.
  • We will store the results of the dot notation into a variable and pass it on to a new function that we’ll use to display the array results on to the page.
  • Inside the function, let’s log the value passed onto the console and make sure our code is all good.

The Javascript snippet

function displaySearchResults(x){
.
.
fetch(url)
.then(function(response) {
return(response.json());
})
.then(function(data){
let resultsArray = data.query.search;
resultsOnPage(resultsArray);
})
.catch(function () {
console.log('An error occurred');
});
}


function resultsOnPage(myArray){
console.log(myArray);

}

Step 8: Console logging the contents we need from the JSON.

  • When we examine the results from the previous step, we can see that each object has keys such as title, snippet, and timestamp for each of the results. We can use the title and snippet to display the results on the page.
  • Wikipedia API does not provide the URL for each result but we need this to be able to link to each page in the search results.
  • Wikipedia URLs always begin with ‘https://en.wikipedia.org/wiki/’ followed by the title of the article with the spaces replaced by underscores. For eg: if the title of the article is Elon Musk, the URL becomes ‘https://en.wikipedia.org/wiki/Elon_Musk’.
  • If the URL has spaces, eg:’https://en.wikipedia.org/wiki/Elon Musk’, it will automatically be directed to the URL with underscores, eg: ‘https://en.wikipedia.org/wiki/Elon_Musk’.
  • In our case, we will append the title of the result to the URL ‘https://en.wikipedia.org/wiki/’.
  • For best practices, we will encode the URL using the encodeURI method, so spaces are replaced by %20.
  • In our example, encodeURI(‘https://en.wikipedia.org/wiki/Elon Musk’) will return https://en.wikipedia.org/wiki/Elon%20Musk which will automatically redirect to the URL with underscores – https://en.wikipedia.org/wiki/Elon_Musk.
  • Using a forEach loop, we will read each of the array items and store the title, snippet, and URL into variables and log the variables to the console to test the code.

The Javascript snippet

function resultsOnPage(myArray){
myArray.forEach(function(item){
let itemTitle = item.title;
let itemSnippet = item.snippet;
let itemUrl = encodeURI(`https://en.wikipedia.org/wiki/${item.title}`);
console.log(itemTitle);
console.log(itemSnippet);
console.log(itemUrl);


})

}

Step 9: Displaying the contents of the JSON on the page.

  • Now that we have all the results we want to display, let’s start adding them to the DOM. First, hook onto the empty div we created in step 1. Using the innerHTML property, we reset the HTML inside to an empty string.
  • Using the DOM API insertAdjacentHTML, we append h2 heading HTML tag and the search term to the empty div, to improve the readability of the app.
  • Inside the forEach loop, we use the insertAdjacentHTML API, to append the title, snippet and link from the Wikipedia result that we got from the previous step to the DOM.
  • We will add some CSS to the output to make the results look better.

The Javascript snippet

resultsList.innerHTML = " ";
resultsList.insertAdjacentHTML('beforeend', `<h2>Search Results for ${searchInput.value} </h2>`);
myArray.forEach(function(item){
let itemTitle = item.title;
let itemSnippet = item.snippet;
let itemUrl = encodeURI(`https://en.wikipedia.org/wiki/${item.title}`);


resultsList.insertAdjacentHTML('beforeend',
`<div class="resultItem">
<h3 class="resultTitle">
<a href="${itemUrl}" target="_blank" rel="noopener">${itemTitle}</a>
</h3>
<p class="resultSnippet"><a href="${itemUrl}"  target="_blank" rel="noopener">
${itemSnippet}</a></p>
</div>`
);
})

The CSS snippet

.resultItem{
background: #f8f5f1;
border-radius:3px;
margin: 10px 10px 10px 0;
padding:10px;
text-align: left;
white-space: normal;
font-style: italic;
}
.resultItem:hover{
border-left:5px solid #443328;
}
Notes:
  • forEach loop, we use the insertAdjacentHTML takes two arguments – The position where we want to append the element (in our case, beforeend) and a string containing the HTML to insert on the page.
  • We are using Temperate literal in the second argument, to get the results in a more readable format.

To see the Wikipedia search in action, please check out the demo link below. You can type in any text into the text field and click the “Search” button. The results of the search will be displayed below the form with a title and a snippet of the article. You can click on any of the results to go to the relevant Wikipedia search article.