未捕获(在承诺中)TypeError:无法读取未定义

时间:2018-05-19 20:59:30

标签: javascript api async-await fetch

我正在尝试从OMDB数据库中获取数据以显示电影。最初我实现了点击事件来调用数据,没有发现错误。但是当我切换到 keyup 事件时,我收到了这个错误。

未捕获(承诺)TypeError:无法读取未定义的属性'forEach' at fetchMovie.getMovies.then.res(main.js:27) fetchMovie.getMovies.then.res @ main.js:27 异步功能(异步) 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();
    })

SCEENSHOT

enter image description here

使用空图像修复的ERROR也添加了keyup事件。控制台中没有错误

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

1 个答案:

答案 0 :(得分:3)

如果您看到首先获得的日志屏幕截图,则会记录undefined。这很可能是因为每次按键都会进行提取,如果您在API中搜索单个字符(,这是您使用第一个keyup 发送的内容),则无法获得结果因而forEach失败了。

在执行forEach之前检查数据是否有值,或者如果搜索字符串是单个字符,则不要发送提取。

let data = res.moveData.Search
let output = ''
if (!data) return; //early break if not results where returned.

或将if (input !== '') {更改为

if (input.trim().length > 1) { // only do the fetch if more than one characters where entered

虽然即使您发送了多个字符也可能仍然没有结果,因此第一种方法更安全。