admin管理员组

文章数量:1410730

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(`/?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(`/?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 = `.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();
})

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./?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./?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/wikipedia/mons/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();
})
Share Improve this question edited Aug 11, 2023 at 21:27 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 19, 2018 at 20:59 ExcExc 1,6554 gold badges18 silver badges32 bronze badges 13
  • You should definetly add proper error handling if you are depending on user input – Jonas Wilms Commented May 19, 2018 at 21:02
  • 1 There is probably an error in how you fetch the movies. I'm not familiar with the API, but you may have a typo two lines above your error. You typed res.moveData when you may have meant res.movieData – Michael Karpinski Commented May 19, 2018 at 21:03
  • 1 Try logging what res.moveData is. – CertainPerformance Commented May 19, 2018 at 21:04
  • @MichaelKarpinski There is no movieData anywhere though, moveData works just fine - pretty sure it was just an abbreviation, not a typo – CertainPerformance Commented May 19, 2018 at 21:04
  • 1 If res.moveData is an array of movies, then it's not an object with a property of Search, so of course accessing moveData.Search would be undefined... – CertainPerformance Commented May 19, 2018 at 21:09
 |  Show 8 more ments

1 Answer 1

Reset to default 4

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.

本文标签: javascriptUncaught (in promise) TypeError Cannot read property 39forEach39 of undefinedStack Overflow