Не удается прочитать свойство 'map' из undefined, даже если API правильно выбран в консоли в Async - PullRequest
0 голосов
/ 27 февраля 2020

Привет! Я пытаюсь создать веб-приложение поиска новостей на основе API с помощью JS. Итак, вот функция, где я получаю ошибку

async function fetchUsers(searchTerm, searchLimit, sortBy){
//RETURNS PROMISES
let url=`some api parameters searchTerm, SearchLimit and sorby is passed`;

const res=await fetch(url);
const data=await res.json();
const article = [];


document.getElementById("container").innerHTML=`
${data.article.map(function(post){
  //NEWSCARD
  return(`
  <ul id="news-article" style="list-style-type:none;">
    <li class="article">
      <div class="card mb-2">
        <img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
        <div class="card-body">
          <h2 class="article-title" class="card-title">${post.title}</h2>
          <p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
          <a class="article-link" href="${post.url}" target="_blank
          " class="btn btn-primary">Read More</a>
          <hr>
          <span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span> 
          <span class="badge badge-dark">Score: ${post.score}</span>
        </div>
      </div>
    </li>
  </ul>
  `)
}
 .join('') 
  )}} fetchUsers();

Основная ошибка наблюдается в $ {data.article.map (function (post) {

) Может кто-нибудь подсказать, что может быть Возможная причина для этого?

enter image description here

Спасибо

Ответы [ 4 ]

0 голосов
/ 27 февраля 2020

Единственный способ сузить и найти проблему - это сначала написать код в чистом виде.

Я бы предложил разбить ваш код на управляемые части и попробовать функции отладки в браузере с помощью отладчик или console.log () работает очень хорошо.

Есть еще лучшие варианты, такие как TDD, где вы можете написать свой код и проверить его с помощью кода, чтобы получить больше уверенности с помощью таких инструментов, как jest

NOTE: pseudo code
function getPosts() { 
   return posts
}

function renderPost(post) { 
   return `<div>${post}</div> ` 
}

function render() {
   const posts = getPosts()
   console.info('post -> ', posts)
   const postsMarkup = posts.map((post) => renderPost(post)).join('');
   console.info('postsMarkup -> ', postsMarkup)
   document.getElementById('container').innerHTML = postMarkup
}

0 голосов
/ 27 февраля 2020

Вы также можете сделать это без ключевых слов async и await и просто использовать обратный вызов в выражении .then, например:


function fetchUsers(searchTerm, searchLimit, sortBy){

  let url=`some url based on params`;

  fetch(url)
    .then( res => res.json() )
    .then( data => populateList(data) )

}

function populateList(data) {
    const innerHTML = data.articles.map(post => `
    <ul id="news-article" style="list-style-type:none;">
        <li class="article">
            <div class="card mb-2">
                <img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
                <div class="card-body">
                    <h2 class="article-title" class="card-title">${post.title}</h2>
                    <p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
                    <a class="article-link" href="${post.url}" target="_blank" class="btn btn-primary">Read More</a>
                    <hr>
                    <span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span> 
                    <span class="badge badge-dark">Score: ${post.score}</span>
                </div>
            </div>
        </li>
    </ul>
    `);

    document.getElementById('container').innerHTML = innerHTML;
}

fetchUsers(searchTerm, searchLimit, sortBy);

Кроме того, перехватывая комментарий Мисира Джафарова, массив в вашем data объекте называется articles, но вы пытаетесь отобразить из article. Я чувствую, что у тебя все еще будут проблемы без этой опечатки, но это определенно тебя повесит. Спасибо @Misir Джафаров

0 голосов
/ 27 февраля 2020

Проблема (из наблюдения за ошибкой в ​​консоли) заключается в том, что ваш код пытается получить доступ к несуществующему свойству.

Без доступа к точным данным, которые вы используете, он ' Было бы невозможно сообщить вам, в чем именно заключается проблема. Тем не менее, вот несколько шагов, которые я бы предпринял для диагностики проблемы:

  1. Установите точку останова (debugger) или console.log(data) сразу после назначения data, чтобы вы могли наблюдать it.
  2. Либо кликните по переменной data в инструментах разработчика вашего браузера, либо проверьте предположения, которые ваш код делает программно.

С точки зрения программной проверки предположений вашего кода:

  1. Убедитесь, что data является объектом, запустив typeof data должен вернуть object
  2. Убедитесь, что data действительно имеет свойство article, запустив Object(data).hasOwnProperty('article')
  3. Убедитесь, что data.article является массивом, запустив Array.isArray(data.article)
  4. Убедитесь, что каждый article в data имеет selfText, subreddit, score (используя шаг 2)

Я предполагаю, что вы обнаружите несоответствие между вашим кодом и данными в этом процессе. Если нет, я хотел бы знать, где вы приземлиться.

0 голосов
/ 27 февраля 2020

Что происходит, так это то, что раздел document.getElementByid вызывается асинхронно, возможно, в то время, когда данные ничего не возвращают или когда переменная article даже не объявлена, вы можете попробовать это:

async function getData() {
    const res = await fetch(url);
    const data = await res.json();

    populateList(data);
}

function populateList(article) {
    const innerHTML = article.map(post => `
    <ul id="news-article" style="list-style-type:none;">
        <li class="article">
            <div class="card mb-2">
                <img class="article-image" class="card-img-top" src="${post.urlToimage}" alt="Card image cap">
                <div class="card-body">
                    <h2 class="article-title" class="card-title">${post.title}</h2>
                    <p class="article-description" class="card-text">${truncateString(post.selftext, 100)}</p>
                    <a class="article-link" href="${post.url}" target="_blank" class="btn btn-primary">Read More</a>
                    <hr>
                    <span class="article-author" class="badge badge-secondary">Subreddit: ${post.subreddit}</span> 
                    <span class="badge badge-dark">Score: ${post.score}</span>
                </div>
            </div>
        </li>
    </ul>
    `);

    document.getElementById('container').innerHTML = innerHTML;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...