responseJson - Cannot access when put inside of function - javascript

In my javascript file, I've noted where my problems are on lines 19, 30, and 35 of my JS file. I can get responseJson to log to the console in the getUserRepos() function, but if I try to log it to the console inside of the displayResults() function, I get an error. Once I can access it, I'll be able to loop through it and retrieve the info I need to complete this assignment.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="main.css">
<title>GitHub User API</title>
</head>
<body>
<header>
<h1>Search for GitHub User Repos</h1>
</header>
<form>
<label for="input"></label>
<input type="text" id="input" class="input" name="input" value="DusVen44">
<input type="submit" value="Search">
</form>
<p class="error-message"></p>
<section id="results" class="hidden">
<h2>Search Results</h2>
<ul class="results-list">
</ul>
</section>
<script src="https://code.jquery.com/jquery-3.5.0.js"
integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc="
crossorigin="anonymous"></script>
<script src="index.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
.hidden {
display: none;
}
ul {
list-style-type: none;
}
console.log("hey")
let searchInput = $("#input").val();
console.log(searchInput)
let baseURL = "https://api.github.com/users/" + searchInput + "/repos";
console.log(baseURL)
function getUserRepos() {
fetch(baseURL)
.then(response => {
if (response.ok) {
return response.json();
} throw new Error(response.statusText);
})
.then(responseJson => console.log(responseJson))
.then(responseJson => displayResults())//Here is where I'm calling the function
.catch(error => alert("Something went wrong"));
}
function submitForm() {
$("form").submit(function(event) {
event.preventDefault();
getUserRepos();
})
}
//This function works until I try to access responseJson
function displayResults() {
console.log("Hey");
$(".results-list").empty();
$(".results-list").append(`<h1>This is a test</h1>`);
console.log(responseJson);//This causes an error
// responseJson.each(function(data) {
// console.log(data);
// });
// $(".results-list").append(
// `<li><h2>${responseJson[i].name}</h2>
// <h2><a href="${responseJson[i].html_url}</h2>
// </li>`
// )
// };
$("#results").removeClass("hidden");
}
// getUserRepos()
submitForm()

It's because you are not passing responseJson to the function. responseJson is only available in .then scope.
The easiest way for this to work is to do
.then(responseJson => displayResults(responseJson))
function displayResults(responseJson ) {
//your code
//console.log(responseJson);
}
//edit
.then(responseJson => displayResults(responseJson))
can be shortened to
.then(displayResults)
because you don't need to create arrow function to pass the responseJson to other function, just call it directly.

When you call displayResults you are not passing responseJson as a parameter. That is the only issue here becuase responseJson is not defined inside displayResults function.

Related

Javascript Export JSON objects to Excel File

I'm Trying to Export this JSON table as an Excel file using Javascript so this is what I have tried and I get this error on the Console log
this is prepear.php file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.2/xlsx.full.min.js"></script>
<script src='https://unpkg.com/tesseract.js#v2.1.0/dist/tesseract.min.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- <script src='excelexportjs.js'></script> -->
<script src='main.js'></script>
<script src="filesaver.js"></script>
<div class="container mt-5 ">
<pre id="json"></pre>
<button class="btn btn-primary" onclick="downloadAsExcel(json.innerHTML)">download excel</button>
</div>
</head>
<body>
</body>
</html>
and the second file is main.js
async function readFile(fileName)
{
console.log({
fileName
});
return await Tesseract.recognize(fileName, 'ara', {
logger: m => console.log(m)
}); // fake it ...
}
async function parseDataFromTextAndPropertyNames(text, propertyNames)
{
console.log({
text, propertyNames
});
return propertyNames .reduce((table, key) => Object.assign(table, {
[ key ]: RegExp(`${ key }\\W+(\\w+)`) .exec(text)?.[1] ?? '' }
), {});
}
async function writeParsedTextDataAsJSON(fileName, table)
{
console.log({
table
});
JSON.stringify({
table
}) // fake it ...
return (await new Promise(resolve => setTimeout(() => {
console.log({ fileName, json: JSON.stringify({ table }) });
resolve({ success: true });
}, 1500) ));
and finally, filesaver.js
The Console Log
Uncaught TypeError: r.forEach is not a function at rb (xlsx.full.min.js:23:18346) at Object.tb [as json_to_sheet] (xlsx.full.min.js:23:19000) at downloadAsExcel (mains.js:61:32) at HTMLButtonElement.onclick (prepare.php:16:83)

Why is my fetch request not executing inside an event listener callback function?

Just getting the hang of API calls and fetch and have put together the below code to fetch some info from the Trip Advisor API and log a message to the console using this info.
When I call the fetch request function it logs to the console just fine, but as soon as I wrap it in an event listener callback it no longer executes, why is this?
Appreciate any help!
//This is the fetch function kept in a file names request.js
const findRest = async (reviews, closed) => {
const respond = await fetch(
"https://tripadvisor1.p.rapidapi.com/restaurants/list-by-latlng?limit=30&currency=EUR&distance=2&lunit=km&lang=en_US&latitude=53.3498&longitude=-6.2603",
{
method: "GET",
headers: {
"x-rapidapi-host": "tripadvisor1.p.rapidapi.com",
"x-rapidapi-key": /* my rapidapi key */
}
}
);
if (respond.status === 200) {
let data = await respond.json();
let newData = await data.data;
let data1 = await newData.filter(
review => parseInt(review.num_reviews) >= reviews
);
let data2 = await data1.filter(close => close.is_closed == closed);
return data2;
} else {
throw new Error("Could not provide results within specified parameters");
}
};
//This is the event listener kept in a file names app.js - both files are active and no problems communicating with each other
document.querySelector(".subButton").addEventListener("click", e => {
e.preventDefault();
console.log("click");
const userReviews = parseInt(document.querySelector(".userRev").value);
const userClose = document.querySelector(".userClose").value;
findRest(userReviews, userClose)
.then(data => {
data.forEach(element => {
console.log(
`${element.name} matches your search criterea and is located at ${element.address}
To make a booking, please call ${element.phone}`
);
});
})
.catch(err => {
console.log(err);
});
});
//HTML below
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>What Wine?</title>
<meta name="author" content="Phil My Glass" />
<meta
name="description"
content="An app to help you find the wine you like or something new based on your preferences"
/>
<meta name="keywords" content="wine" />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<header>
<h1>What Restaurant?</h1>
</header>
<main>
<form>
<input class="userRev" /><br />
<input class="userClose" />
<button class="subButton" type="submit">Find!</button>
</form>
</main>
</body>
<script src="req.js" type="text/Javascript"></script>
<script src="app.js" type="text/Javascript"></script>
</html>
Those two lines look like they could break the thread:
const userReviews = parseInt(document.querySelector(".userRev").value);
const userClose = document.querySelector(".userClose").value;
If either one of document.querySelector(".userRev"), document.querySelector(".userClose") is null, that will be uncaught TypeError.
Will know for sure with the HTML.

Typeahead JS Autocomplete not working - can't find anything

I want to make a autocomplete function on my input with existing titles from database, but seems that doesn't work. I don't know what's the problem but when I try to write something, notting happens.
Here is my controller
public function search()
{
return view('search-me');
}
public function autocomplete(Request $request)
{
$data = Models::select("email")->where("email", "LIKE","%{$request->input("query")}%")->get();
return response()->json($data);
}
Here is my route
Route::get('search-me', array('as' => 'search', 'uses' => 'AdminNewsController#search'));
Route::get('autocomplete',array('as' => 'autocomplete', 'uses' => 'AdminNewsController#autocomplete'));
Here is my view
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.js"></script>
</head>
<body>
<div class="container">
<h1> test</h1>
<input type="text" class="typeahead form-control">
</div>
</body>
<script type="text/javascript">
var path = "{{ route('autocomplete') }}";
$('input.typeahead').typeahead({
source: function (query, process){
return $.get(path, { query: query}, function (data) {
return process(data);
});
}
});
</script>
</html>
I'm using Laravel 5.2 but I guess is working on mine too. Here is the tutorial : https://www.youtube.com/watch?v=3AiMsvobceY

How to write a JavaScript download function in my YouTube MP4 & MP3 Downloader

// put your own value below!
const apiKey = "AIzaSyCGKrLxvpot6hrekFHQTPaCGeOFj92T3ao";
const searchURL = "https://www.googleapis.com/youtube/v3/search";
function formatQueryParams(params) {
const queryItems = Object.keys(params).map(
key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
);
return queryItems.join("&");
}
function displayResults(responseJson) {
// if there are previous results, remove them
console.log(responseJson);
$("#results-list").empty();
// iterate through the items array
for (let i = 0; i < responseJson.items.length; i++) {
// for each video object in the items
//array, add a list item to the results
//list with the video title, description,
//and thumbnail
$("#results-list").append(
`<li><h3>${responseJson.items[i].snippet.title}</h3>
<p>${responseJson.items[i].snippet.description}</p>
<img src='${responseJson.items[i].snippet.thumbnails.default.url}'>
</li>`
);
}
//display the results section
$("#results").removeClass("hidden");
}
async function downloadVideo(videoId) {
console.log(videoId);
const response = await fetch(`https://getvideo.p.rapidapi.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D${videoId}`, {
headers: {
"X-RapidAPI-Host": "getvideo.p.rapidapi.com",
"X-RapidAPI-Key": "d390d7b0e9msh42dc09f4e07e285p1486c4jsne0a4edb9e61e"
}
});
const data = await response.json();
return {
audio: data.streams.filter(stream => {
return stream.format === "audio only";
})[0].url,
video: data.streams.filter(stream => {
return stream.format !== "audio only";
})[0].url
};
}
function getYouTubeVideos(query, maxResults = 50) {
const params = {
key: apiKey,
q: query,
part: "snippet",
maxResults,
type: "video"
};
const queryString = formatQueryParams(params);
const url = searchURL + "?" + queryString;
console.log(url);
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error(response.statusText);
})
.then(responseJson => downloadVideo(responseJson.items[0].id.videoId))
.then(download => console.log(download))
// .then(responseJson => displayResults(responseJson))
.catch(err => {
$("#js-error-message").text(`Something went wrong: ${err.message}`);
});
}
function watchForm() {
$("form").submit(event => {
event.preventDefault();
const searchTerm = $("#js-search-term").val();
const maxResults = $("#js-max-results").val();
getYouTubeVideos(searchTerm, maxResults);
});
}
$(watchForm);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>YouTube video finder</title>
<link rel="stylesheet" href="style\style.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"
></script>
</head>
<body>
<div class="container">
<div class="left">
<h1 class="finder-heading">Download a YouTube video</h1>
<form id="js-form">
<label for="search-term"></label>
<input
class="search-input"
type="text"
name="search-term"
id="js-search-term"
required
placeholder="Search YouTube Videos..."
/>
<label for="max-results"></label>
<input
class="max-number"
type="number"
name="max-results"
id="js-max-results"
value="10"
/>
<input class="go-button" type="submit" value="Search" />
</form>
</div>
<!-- <div class="right">
<h1 class="downloader-heading">Download a YouTube video</h1>
<input class="URL-input" placeholder="Paste YouTube link here..." />
<button class="download-button">
<i class="fa fa-download"></i> Download
</button>
</div> -->
<p id="js-error-message" class="error-message"></p>
<section id="results" class="hidden">
<h2>Search results</h2>
<ul id="results-list"></ul>
</section>
</div>
<script src="apps\app.js"></script>
</body>
</html>
I am making a web app that is using a 2 API mashup of both youtube API and GET Video and Audio URL API. The problem that I am having is that I don't know how to code the javascript needed in the download portion in this project...
For the moment I have the javascript coded to a point where if you run it and inspect in google chrome you will see in the console how it captures both the audio file and video file of whatever video link you choose to insert into the input.
I expect for this to capture the video produce a thumbnail in the HTML with a given option of downloading MP4 or MP3
The issue is the order of your .then()'s. You are returning data with each call, and in one you return a console.log(), which will be undefined. You can fix it like this:
function getYouTubeVideos(query, maxResults = 50) {
const params = {
key: apiKey,
q: query,
part: "snippet",
maxResults,
type: "video"
};
const queryString = formatQueryParams(params);
const url = searchURL + "?" + queryString;
console.log(url);
fetch(url)
.then(r => r.json())
.then(data => {
displayResults(data);
return downloadVideo(data.items[0].id.videoId);
})
.then(download => console.log(download))
.catch(err => {
$("#js-error-message").text(`Something went wrong: ${err.message}`);
});
}
i use my API Key and its work
const apiKey = "Your Key";
const searchURL = "https://www.googleapis.com/youtube/v3/search";
function formatQueryParams(params) {
const queryItems = Object.keys(params).map(
key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
);
return queryItems.join("&");
}
function displayResults(responseJson) {
console.log(responseJson);
$("#results-list").empty();
for (let i = 0; i < responseJson.items.length; i++) {
$("#results-list").append(
`<li><h3>${responseJson.items[i].snippet.title}</h3>
<p>${responseJson.items[i].snippet.description}</p>
<img src='${responseJson.items[i].snippet.thumbnails.default.url}'>
</li>`
);
}
$("#results").removeClass("hidden");
}
async function downloadVideo(videoId) {
console.log(videoId);
const response = await fetch(`https://getvideo.p.rapidapi.com/?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D${videoId}`, {
headers: {
"X-RapidAPI-Host": "getvideo.p.rapidapi.com",
"X-RapidAPI-Key": "d390d7b0e9msh42dc09f4e07e285p1486c4jsne0a4edb9e61e"
}
});
const data = await response.json();
return {
audio: data.streams.filter(stream => {
return stream.format === "audio only";
})[0].url,
video: data.streams.filter(stream => {
return stream.format !== "audio only";
})[0].url
};
}
function getYouTubeVideos(query, maxResults = 50) {
const params = {
key: apiKey,
q: query,
part: "snippet",
maxResults,
type: "video"
};
const queryString = formatQueryParams(params);
const url = searchURL + "?" + queryString;
console.log(url);
fetch(url)
.then(r => r.json())
.then(data => {
displayResults(data);
return downloadVideo(data.items[0].id.videoId);
})
.then(download => console.log(download))
.catch(err => {
$("#js-error-message").text(`Something went wrong: ${err.message}`);
});
}
function watchForm() {
$("form").submit(event => {
event.preventDefault();
const searchTerm = $("#js-search-term").val();
const maxResults = $("#js-max-results").val();
getYouTubeVideos(searchTerm, maxResults);
});
}
$(watchForm);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>YouTube video finder</title>
<link rel="stylesheet" href="style\style.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"
></script>
</head>
<body>
<div class="container">
<div class="left">
<h1 class="finder-heading">Download a YouTube video</h1>
<form id="js-form">
<label for="search-term"></label>
<input
class="search-input"
type="text"
name="search-term"
id="js-search-term"
required
placeholder="Search YouTube Videos..."
/>
<label for="max-results"></label>
<input
class="max-number"
type="number"
name="max-results"
id="js-max-results"
value="10"
/>
<input class="go-button" type="submit" value="Search" />
</form>
</div>
<!-- <div class="right">
<h1 class="downloader-heading">Download a YouTube video</h1>
<input class="URL-input" placeholder="Paste YouTube link here..." />
<button class="download-button">
<i class="fa fa-download"></i> Download
</button>
</div> -->
<p id="js-error-message" class="error-message"></p>
<section id="results" class="hidden">
<h2>Search results</h2>
<ul id="results-list"></ul>
</section>
</div>
<script src="apps\app.js"></script>
</body>
</html>

JavaScript function is undefined although it's loaded

I'm doing my homework for a JS course and I face a strange problem. I've made a request 'module' that I'm at the very beginning right after jquery then I'm loading the essential js scripts but when I try to use a function from the request module in another script file it always throws a TypeError undefined. The strange is that when I console.log the object it is' not undefined and everything is all right. I can't seem to figure it out why this is happening ... and I need some guideline
Here is part of the code:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SeenIt</title>
<link rel="stylesheet" href="style/site.css">
<link rel="stylesheet" href="style/post.css">
<link rel="stylesheet" href="style/header.css">
<link rel="stylesheet" href="style/menu.css">
<link rel="stylesheet" href="style/notifications.css">
<link rel="stylesheet" href="style/submit.css">
<link rel="stylesheet" href="style/comments.css">
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="./scripts/request.js"></script>
<script src="../node_modules/handlebars/dist/handlebars.min.js"></script>
<script src="./scripts/pageView.js"></script>
<script src="./scripts/app.js"></script>
</head>
<body>
<div id="container">
</div>
</body>
</html>
My JS Request Module
let request = (function (){
const appKey = 'kid_rkR4UTRnb';
const appSecret = 'd3e9f15502a740fcb1413d7ffe109ab5';
const baseUrl = 'https://baas.kinvey.com';
function createAuth(type)
{
let authorize = {"Content-Type": "application/json"};
if(type === 'basic')
{
authorize.Authorization = "Basic " + btoa(appKey + ':' + appSecret);
}
else if(type === 'kinvey')
{
authorize.Authorization = "Kinvey " + localStorage.getItem('authtoken');
}
return authorize;
}
function makeRequest(destination, endpoint, method, authorization, data)
{
let req = {
url: baseUrl + '/' + destination + '/' + endpoint,
method: method,
headers: createAuth(authorization),
};
if(data != undefined) req.data = JSON.stringify(data);
$.ajax(req);
}
function register(username, password)
{
let data = {
"username": username,
"password": password
};
return makeRequest('user', appKey, 'POST', 'basic', data);
}
function logIn(username, password)
{
let data = {
"username": username,
"password": password
};
return makeRequest('user', appKey + '/login', 'POST', 'basic', data);
}
function logout()
{
makeRequest('user', appKey + '/_logout', 'POST', 'kinvey');
}
return {
createAuth,
register,
logIn,
logout
}
})();
Main JS App file
$(() => {
let main = $('#container');
initialState();
$(document).ajaxStart(() => $('#loadingBox').show());
$(document).ajaxComplete(() => $('#loadingBox').hide());
$('#infoBox').click(() => $('#infoBox').hide());
$('#errorBox').click(() => $('#errorBox').hide());
$(document).on('submit', '#loginForm', login);
async function viewPage(page)
{
if(page == 'home')
{
main.html(await loadWelcome(isLoggedIn()));
}
}
// initial functions
function initialState()
{
viewPage('home');
}
///////////////
// session control
function login(e)
{
e.preventDefault();
let loginForm = $(this);
let name = loginForm.find('input[name="username"]').val();
let password = loginForm.find('input[name="password"]').val();
request.logIn(name, password) // TYPEERROR UNDEFINED ?!?
.then(data => {
request.saveSession(data);
this.reset();
viewPage('home');
})
}
});
It crashes when you try to invoke the then() method because the request.logIn() function returns undefined instead of a promise. This can be traced to the makeRequest() function which doesn't return anything, i.e. undefined.
Your last line in the makeRequest() function needs to be:
return $.ajax(req);
Please try return object on JS Request Module like this,
return {
createAuth: createAuth,
register: register,
logIn: logIn,
logout: logout
}
You can try <script> attributes for the correct loading scripts:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SeenIt</title>
<link rel="stylesheet" href="style/site.css">
<link rel="stylesheet" href="style/post.css">
<link rel="stylesheet" href="style/header.css">
<link rel="stylesheet" href="style/menu.css">
<link rel="stylesheet" href="style/notifications.css">
<link rel="stylesheet" href="style/submit.css">
<link rel="stylesheet" href="style/comments.css">
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/handlebars/dist/handlebars.min.js"></script>
<script defer src="./scripts/request.js"></script>
<script defer src="./scripts/pageView.js"></script>
<script defer src="./scripts/app.js"></script>
</head>
<body>
<div id="container">
</div>
</body>
</html>
in your code, function makeRequest doesn't return any value, so it will return undefined. try returning the value from the makeRequest function.

Categories