Skip to content

Instantly share code, notes, and snippets.

@alexmanzo
Last active August 4, 2020 15:26
Show Gist options
  • Save alexmanzo/687dd41053bf8fcf07b6dcc2b544a73d to your computer and use it in GitHub Desktop.
Save alexmanzo/687dd41053bf8fcf07b6dcc2b544a73d to your computer and use it in GitHub Desktop.
Movie Search
// This file contais three solutions: One using promises, my original solution to the HackerRank problem, and one using Axios //
// ----- Solution Using Promises ------ //
var https = require('https');
const getMovieData = (url) => {
return new Promise((resolve, reject) => {
https.get(url, res => {
let body = "";
res.on("data", chunk => (body += chunk));
res.on("end", () => {
resolve(JSON.parse(body));
});
res.on("error", err => {
reject(err);
});
});
});
}
const getMovieTitles = async query => {
if (query === '') return null
const trimmedQuery = query.trim()
const url = `https://jsonmock.hackerrank.com/api/movies/search/?Title=${trimmedQuery}`;
const movieData = await getMovieData(url).catch(err => console.log(err))
const titles = []
const pageNum = movieData.total_pages
let counter = pageNum
while (counter > 0) {
const pageResults = await (getMovieData(`${url}&page=${counter}`).catch(err => console.log(err)))
pageResults.data.forEach(movie => {
titles.push(movie.Title)
})
counter--
}
console.log(titles.sort())
}
getMovieTitles('spiderman')
// ----- Original Solution ------ //
const https = require("https");
// Request to retrive # of result pages
const getPages = (url, callback) => {
https
.get(url, res => {
// Initialize body string
let body = "";
// As request receives data, add each "chunk" of data to the body object to create one item.
res.on("data", chunk => (body += chunk));
// Pull total_pages from data, return callback function. Null takes place of err paramter
res.on("end", () => {
return callback(null, JSON.parse(body).total_pages);
});
})
// return callback for errors
.on("error", err => {
return callback(err, null);
});
};
// Request to retrieve movie data with page # added to URL
const getMovieData = (urls, callback) => {
// Initializa array to store titles
const titles = [];
// Counter to track how many pages we're querying
let page = 1;
// Loop through each URL to pull titles for each page.
urls.forEach(url => {
https.get(url, res => {
let body = "";
res.on("data", chunk => (body += chunk));
res.on("end", () => {
const movies = JSON.parse(body).data;
// Iterate through each movie in the data object, and add their titles to the titles array.
movies.forEach(movie => titles.push(movie.Title));
// Check if the page variable above is same as lenght of urls. If not, callback function is returned.
return page === urls.length ? callback(null, titles) : page++;
});
res.on("error", err => {
return callback(err, null);
});
});
});
};
const getMovieTitles = substr => {
// Log message to add a search term if blank search is submitted
if (substr === "") {
console.log('Please enter a search term.');
}
// Trim substr to account for any leading or trailing whitespace
const trimmedQuery = substr.trim()
// Store base URL with trimmed query added.
const url = `https://jsonmock.hackerrank.com/api/movies/search/?Title=${trimmedQuery}`;
// Call function to get # of pages
getPages(url, (err, totalPages) => {
// Initialize array to store URLs for each page
const urls = [];
if (err) {
console.log(err);
}
// Generate a URL for however many pages we need to send a request for
for (let page = 1; page <= totalPages; page++) {
urls.push(`${url}&page=${page}`);
}
// Call function to get titles. Title array is returned
getMovieData(urls, (err, titles) => {
if (err) {
console.log(err);
}
// Sort the titles and log to console
console.log(titles.sort());
});
});
};
getMovieTitles("spiderman");
// ----- Axios Solution ------ //
// Axios or Fetch would be my preferred method since it gives the same result with much less code.
const axios = require('axios')
const getTitlesByPage = async (url, page) => {
const pageUrl = `${url}&page=${page}`
return axios.get(`${url}&page=${page}`)
}
const getMovieTitles = async substr => {
// Set up array to add titles to
const titles = []
// Trim to remove whitespace
const trimmedQuery = substr.trim()
const url = `https://jsonmock.hackerrank.com/api/movies/search/?Title=${trimmedQuery}`
// Destructure response to get directly to data (this bypasses header responses)
const { data } = await axios.get(url)
const totalPages = data.total_pages
// Loop through to query each page of results, then push titles to array.
for (let page=1; page<=totalPages; page++) {
const { data } = await getTitlesByPage(url, page)
data.data.forEach(movie => {
titles.push(movie.Title)
})
}
// Sort and return
console.log(titles.sort())
}
getMovieTitles('spiderman')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment