Sunday, May 19, 2024
6
rated 0 times [  7] [ 1]  / answers: 1 / hits: 5389  / 5 Years ago, wed, december 18, 2019, 12:00:00

I'm trying to make a call to the Trip Advisor API and return some data using an async/await function.



The async/await function is defined in a file named req.js and the code is below:



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: x-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 then called when an event listener fires by clicking a button in a small form. This code is in a file named app.js and is below:



document.getElementById(subButton).addEventListener(click, function(e) {
const userReviews = parseInt(document.querySelector(.userRev).value);
const userClose = document.querySelector(.userClose).value;

e.preventDefault();
console.log(click);
console.log(e.target.id);

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));
});


And for reference here is the HTML:



<!DOCTYPE html>
<html>
<head>
<meta charset=UTF-8 />
<meta name=viewport content=width=device-width,initial-scale=1 />
<title>API Tester</title>
<meta name=author content=Phil My Glass />
<meta
name=description
content=An app to help me practice my API calling
/>
</head>
<body>
<header>
<h1>What Restaurant?</h1>
</header>
<main>
<form id=form>
<input id=userRev class=userRev /><br />
<input id=userClose class=userClose />
<button id=subButton 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>


When I run the findRest function within the app.js file, but outside the event listener and pass in the arguments as static data it executes just find and prints all the requested data to the console. As soon as I try and run it within the event listener nothing happens. No returned data printing, no error and it's killing me why.



Like I said, it works fine outside the event listener, but I've tried changing the forEach to map and still nothing is being returned. Can someone please help!


More From » ecmascript-6

 Answers
6

Answer



Judging by the comments and your replies: the reason why nothing is a happening is because the data is an empty array.
Array.forEach(callback) only executes the callback when the array contains elements.



The reason why it might be empty is that the filter for restaurant.is_closed probably expects a boolean, whereas you pass in a string (the value of an input element is a string).



It's better to use a checkbox to see if it's checked instead. Otherwise you have to see if the string input matches with 'true' or 'false'.



Code itself



The findRest contains unnecessary awaits.
You should define it as



async function findRest(reviews, closed) {
const response = 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: x-rapidapi-key
}
}
);

if (response.status === 200) {
// The only async call is casting the response to a JavaScript object
const json = await response.json();
console.log(json);
const data = json.data;
// Filtering the array is not async
return data.filter((restaurant) => {
// Adding some additional debugs to prove my hypothesis right
const hasEnoughReviews = restaurant.num_review >= reviews;
const isClosed = restaurant.is_closed === closed;
console.log(`review debug: ${typeof restaurant.num_review}, ${typeof reviews} -> output: ${hasEnoughReviews}`);
console.log(`closed debug: ${typeof restaurant.is_closed}, ${typeof closed} -> output: ${isClosed}`)
return hasEnoughReviews && isClosed

})
} else {
throw new Error(Could not provide results within specified parameters);
}
}


You can also use the async/await in your eventListener callback, creating cleaner code



document.getElementById(subButton).addEventListener(click, async (e) => {
const userReviews = parseInt(document.querySelector(.userRev).value);
// Judging by the filter in the findRest, this should be a boolean?
const userClose = document.querySelector(.userClose).value;

e.preventDefault();
console.log(click);
console.log(e.target.id);

try {
const restaurants = await findRest(userReviews, userClose);
// I think your issue is that restaurants is an empty array
console.log(restaurants)
restaurants.forEach(restaurant => {
console.log(`${restaurant.name} matches your search criterea and is located at ${restaurant.address}
To make a booking, please call ${restaurant.phone}`)
})
} catch (err) {
console.log(err)
}
});

[#5292] Monday, December 16, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
masonm

Total Points: 167
Total Questions: 87
Total Answers: 103

Location: Rwanda
Member since Wed, Jun 8, 2022
2 Years ago
;