Reputation: 1655
I am trying to fetch data form OMDB database to display movies. Initially I have implemented click event to call data and no errors were found. But when I switch to keyup
event I got this error.
Uncaught (in promise) TypeError: Cannot read property 'forEach' of undefined
at fetchMovie.getMovies.then.res (main.js:27)
fetchMovie.getMovies.then.res @ main.js:27
async function (async)
searchInput.addEventListener @ main.js:19
let searchInput = document.getElementById('search')
class fetchData {
constructor() {
this.apiKey = 'here is APIKey'
}
async getMovies(movie) {
const movieRes = await fetch(`http://www.omdbapi.com/?apikey=${this.apiKey}&s=${movie}`)
const moveData = await movieRes.json()
return {
moveData
}
}
}
const fetchMovie = new fetchData
searchInput.addEventListener('keyup', (e) => {
let input = e.target.value
if (input !== '') {
fetchMovie.getMovies(input)
.then(res => {
let data = res.moveData.Search
let output = ''
data.forEach(movie => {
output += `
<div class="col-md-3">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="${movie.Poster}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">${movie.Title}</h5>
<p class="card-text">${movie.Year}</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>`
});
document.getElementById('container').innerHTML = output;
})
}
e.preventDefault();
})
SCREENSHOT
ERROR fixed with empty images also added keyup event. No errors in console
let searchInput = document.getElementById('search');
class fetchData {
constructor() {
this.apiKey = '884df292'
}
async getMovies(movie) {
const movieRes = await fetch(`http://www.omdbapi.com/?apikey=${this.apiKey}&s=${movie}`)
const moveData = await movieRes.json()
return {
moveData
}
}
}
const fetchMovie = new fetchData
searchInput.addEventListener('keyup', (e) => {
let input = e.target.value;
if (input !== '') {
fetchMovie.getMovies(input)
.then(res => {
let data = res.moveData.Search
console.log(data)
if (!data) {
return false
} else {
let output = ''
data.forEach(movie => {
let poster
if (movie.Poster === "N/A") {
poster = `https://upload.wikimedia.org/wikipedia/commons/a/ac/No_image_available.svg`
} else {
poster = movie.Poster
}
output += `
<div class="col-md-3 movie-card">
<div class="card">
<img class="card-img-top" src="${poster}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">${movie.Title}</h5>
<p class="card-text">${movie.Year}</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</div>`
});
document.getElementById('container').innerHTML = output;
}
})
.catch(err => console.log(err))
}
e.preventDefault();
})
Upvotes: 2
Views: 7955
Reputation: 196207
If you see the log screenshot you first get and undefined
logged. That is most likely because your fetch happens for each key press, and if you search the API for a single character (which is what you sent with the first keyup
) you get back no results and thus the forEach
fails.
Either check if data has a value before doing the forEach
or don't even send a fetch if the search string is a single character.
let data = res.moveData.Search
let output = ''
if (!data) return; //early break if not results where returned.
or change if (input !== '') {
to
if (input.trim().length > 1) { // only do the fetch if more than one characters where entered
although you might still get no results even if you sent more than one characters so the 1st approach is safer.
Upvotes: 4