【问题标题】:Why am I getting 'cannot read property 'filter' of undefined' when the array being filtered contains JSON data?当被过滤的数组包含 JSON 数据时,为什么我会得到“无法读取未定义的属性“过滤器”?
【发布时间】:2018-05-02 10:52:44
【问题描述】:

以下代码

const endpoint = 'https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json';
const universities = [];

fetch(endpoint)
    .then(results => results.json())

    .then(data => universities.push(...data));

console.log(universities);

function findMatches(wordToMatch, universities) {
    return universities.filter(uni => {
        const regex = new RegExp(wordToMatch, 'gi');
        return uni.name.match(regex)
    })
}

export default findMatches;

返回下面的错误

'Uncaught TypeError: Cannot read property 'filter' of undefined'

我可以使用 console.log(universities) 记录数据。那为什么我不能过滤呢?仅供参考,数据是一个对象数组。非常感谢任何帮助。谢谢。

【问题讨论】:

  • 你是如何调用 findMatches 的
  • 我很惊讶console.log 记录了任何内容。
  • 请注意,universitiesfindMatches 中的作用域变量与 const universities 不同,除非这是您在调用 findMatches() 时传入的变量
  • 你得到它是因为你试图过滤一个包含 json 数据的数组。
  • 对不起 Linas,我正在另一个文件中调用它。我将它导入到我的主应用程序文件中,然后也在那里调用它。实际文件然后由 webpack 打包。

标签: javascript arrays json api filter


【解决方案1】:

您需要将universities 作为findMatches 函数中的参数删除,因为它会覆盖本地universities 变量的值:

function findMatches(wordToMatch) {
    return universities.filter(uni => {
        const regex = new RegExp(wordToMatch, 'gi');
        return uni.name.match(regex)
    })
}

然后您可以继续使用findMatches 函数,如下所示:

findMatches("hi") // returns a filtered array

编辑:

您的代码中有一个竞争条件,其中可能会调用 findMatches 在您的fetch 完成之前。为了解决这个问题,findMatches 应该像这样返回一个承诺:

const endpoint = 'https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json';
const universities = [];

const promise = fetch(endpoint)
    .then(results => results.json())

    .then(data => universities.push(...data));

console.log(universities);

function findMatches(wordToMatch) {
    return promise.then(() => universities.filter(uni => {
        const regex = new RegExp(wordToMatch, 'gi');
        return uni.name.match(regex)
    }));
}

findMatches("hi").then(arr => console.log(arr));

如果您绝对确定在完成fetch 后始终会调用findMatches,则可以使用第一个解决方案。否则,强烈建议您使用使用承诺的第二种解决方案。

【讨论】:

  • 虽然你是对的,但我认为问题在于因为fetch 是一个异步函数,所以findMatches 导出时universities 数组没有填充.这就是为什么我对console.log 有效的原因感到惊讶;它不应该 - 出于同样的原因。
  • 你是对的@Andy——我正在修改我的答案以纠正错误
  • 有什么方法可以使这个 findMatches() 函数动态化吗?原因是,我想实现一个预先输入的搜索。我目前无法在控制台中调用 findMatches('hi") 函数,因为它返回 findMatches 未定义。为什么会这样?
  • @Leafyshark 你在不同的文件中使用它吗?你有“导出默认 findMatches;”像您在示例中那样位于文件底部?
  • @Leafyshark 听起来您正在直接使用findMatches 返回的值,您不应该这样做,因为返回的值是Promise。相反,您应该使用then() 来捕获承诺解析为的值。例如,您的代码将是:findMatches( $('.search') ).then( (filteredArr) => $('.some-element').html(filteredArr) ); -- 请注意 filteredArr 仅在 then() 函数中可用
【解决方案2】:

我只想让每个人都知道我终于让一切正常了。我必须安装 babel-polyfill 和 babel-preset-env 并添加到 webpack 以使 UglifyJS 与 async await 一起工作并优化包大小。

出于某种原因,我不得不使用 async await 而不是常规的 Promise 来让 HTML 呈现到 DOM 中,但不知道为什么。无论如何,这是最终按预期工作的代码:

UniFetch.js

const endpoint = 'https://raw.githubusercontent.com/Hipo/university-domains-list/master/world_universities_and_domains.json';

const universities = [];

const promise = fetch(endpoint)
    .then(blob => blob.json())
    .then(data => universities.push(...data.slice(8286, 8456)));

function findMatches(wordToMatch) {
    return promise.then(() => universities.filter(uni => {
        const regex = new RegExp(wordToMatch, 'gi');
        return uni.name.match(regex)
    }));
}

async function displayMatches() {
    searchResults.innerHTML = await findMatches(this.value)
        .then(arr => arr.map(uni => {
        return `
            <li>${uni.name}</li>
        `
    }));
}

const searchInput = document.querySelector("input[name='unisearch']");
const searchResults = document.querySelector('.unisearch__results');

searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);

export default findMatches

App.js

import FindMatches from '../UniFetch.js'

FindMatches()

希望这有助于一些人实现预先输入、自动完成的 API 提取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2021-06-03
    • 2021-12-26
    • 2019-07-27
    • 1970-01-01
    • 2017-10-15
    • 2019-03-26
    相关资源
    最近更新 更多