Movie Search & Filter (Vanilla JS) — Headout Round 1 Solved
Overview
This document presents a solution to a front-end coding challenge encountered during a Senior Front-End Engineer interview at Headout. The challenge focuses on building a dynamic movie search and filter component using Vanilla JavaScript. The goal is to implement real-time search functionality based on substring and subsequence matching, along with genre-based filtering, using data fetched from a remote API.
Interview Rounds
Round 1: JavaScript Coding Challenge - Real-Time Movie Search & Filter (Vanilla JS)
The candidate was tasked with implementing the following requirements:
- Render an unstyled list of movies.
- Implement real-time search using substring matching.
- Enable genre-based filtering.
- Support subsequence matching (e.g., input "hp" should match "Harry Potter").
Fetching Movie Data
The provided API endpoint is:
let movieDBJSON = [];
async function fetchMovies() {
let movieDBJSONString = await fetch(
"https://gist.githubusercontent.com/saniyusuf/406b843afdfb9c6a86e25753fe2761f4/raw/523c324c7fcc36efab8224f9ebb7556c09b69a14/Film.JSON"
);
return (movieDBJSON = await movieDBJSONString.json());
}
This function asynchronously fetches movie data from the specified URL and parses it as JSON.
Populating Movies in HTML List
The following code populates the movie data into an HTML list:
async function populateMovieData() {
let movies = await fetchMovies();
let moviesListHTML = document.getElementById("movieList").innerHTML;
movies.forEach((movie) => {
console.log(movie.Title);
moviesListHTML += `<li>${movie.Title}</li>`;
});
document.getElementById("movieList").innerHTML = moviesListHTML;
}
This function retrieves the movie data using fetchMovies(), then iterates through the data and appends each movie title to the HTML list element with the ID movieList.
Searching Movies based on Name, Sub-sequence, and Genre
function searchMovie() {
let searchTerm = document.getElementById("search").value;
let genreTerm = document.getElementById("searchGenre").value;
let movies = movieDBJSON.filter((movie) => {
return (
(movie.Title.toLowerCase().includes(searchTerm.toLowerCase()) ||
isSubsequenceOf(searchTerm.toLowerCase(), movie.Title.toLowerCase())) &&
movie.Genre.toLowerCase().includes(genreTerm.toLowerCase())
);
});
document.getElementById("movieList").innerHTML = "";
let moviesListHTML = "";
movies.forEach((movie) => {
console.log(movie.Title);
moviesListHTML += `<li>${movie.Title}</li>`;
});
document.getElementById("movieList").innerHTML = moviesListHTML;
}
This function filters the movieDBJSON based on the search term and genre. It utilizes both substring matching (includes) and subsequence matching (using the isSubsequenceOf function) on the movie titles, as well as substring matching on the genre.
Checking for Subsequence
function isSubsequenceOf(seq, str) {
let seqPtr = 0;
let strPtr = 0;
while (seqPtr < seq.length && strPtr < str.length) {
if (seq[seqPtr] === str[strPtr]) {
seqPtr++;
}
strPtr++;
}
if (seqPtr === seq.length) {
return true;
}
return false;
}
This function determines if a given string (seq) is a subsequence of another string (str).
HTML Structure
The following HTML structure provides the necessary elements for the movie search and filtering component:
<html>
<head>
<script src="./index.js"></script>
</head>
<body>
Movie list
<input type="text" id="search"
placeholder="Enter movie name"
onchange="searchMovie()" />
<input type="text" id="searchGenre" placeholder="Enter genre" onchange="searchMovie()" />
<script type="module">
import { populateMovieData } from './index.js';
populateMovieData();
</script>
<div>
<ul id="movieList">
</ul>
</div>
</body>
</html>
This HTML includes input fields for movie name and genre search, and a ul element with the ID movieList to display the results. The onchange event on the input fields triggers the searchMovie() function.
Key Takeaways
This challenge demonstrates the importance of understanding string manipulation techniques in JavaScript, including substring and subsequence matching. It also highlights the use of asynchronous JavaScript for fetching data from an API and dynamically updating the DOM. The solution showcases a practical application of these concepts in building an interactive front-end component.
Original Source
This experience was originally published on medium. Support the author by visiting the original post.
Read on medium