2017-11-18 4 views
0

次のコードフィルタリング対象の配列にJSONデータが含まれている場合、なぜ '定義されていない'プロパティ 'filter'を読み取れないのですか?

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; 

私はにconsole.log(大学)を使用してデータを記録することができる

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

以下のエラーを返します。では、なぜそれをフィルタリングできないのですか?参考データはオブジェクトの配列です。どんな助けも大量に評価されています。ありがとうございました。

+1

findMatchesの呼び出し方法 – linasmnew

+0

'console.log'が何かを記録するのに驚いています。 – Andy

+0

'findMatches'の中の' universities'は、 'const universityities'とは異なるスコープ変数です.jsonデータを含む配列をフィルタリングしようとしているため、findMatches()を呼び出すときに渡したものでなければ – charlietfl

答えて

2

それがローカル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 

編集:

コードに競合状態があります。が完了する前に、を と呼びます。あなたは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));

:問題を修正するには、findMatchesはそうのような約束を返す必要があります。それ以外の場合は、約束を使用する第2の解決策を検討することを強くお勧めします。

+0

正しいのですが、 'fetch'は非同期関数'findMatches'がエクスポートされたとき' universities'配列に値が設定されていないので、 'console.log'が動作しているのに驚いています;同じ理由でそうではありません。 – Andy

+0

あなたは正しい@Andy - 私はバグを修正するために私の答えを変更しています –

+0

このfindMatches()関数を動的にすることはできますか?理由は、先読み検索を実装したいです 現在findMatches( 'hi' )関数は、findMatchesを返すときにコンソールで定義されていません。なぜこれはそうですか? – Leafyshark

0

私は最終的には仕事をしていることを皆に伝えたいと思います。私はbabel-polyfillとbabel-preset-envをインストールし、webpackに追加して、UglifyJSを非同期待ちで動作させ、バンドルサイズを最適化する必要がありました。

私は何らかの理由でHTMLをDOMにレンダリングさせるために、通常の約束の代わりにasync awaitを使用しなければなりませんでした。とにかく、ここで予想通り最終的に働いていたコードは次のとおりです。

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を取得します。

関連する問題