По какой-то причине я получаю: fetch (...). Then (...). Then (...). Map не является функцией - PullRequest
0 голосов
/ 21 июня 2020
function getResults(querySearch) {
  api.pageNum += 1;
  refs.list.innerHTML = '';
  const imgBlock = fetch(
    `https://pixabay.com/api/?image_type=photo&orientation=horizontal&q=${querySearch}&page=${api.pageNum}&per_page=12&key=${api.key}`,
  )
    .then(data => {
      return data.json();
    })
    .then(pic => pic.hits)
    .map(item => template(item).join(''));
  refs.list.insertAdjacentHTML('beforeend', imgBlock);
}

Я хотел бы использовать шаблон руля для каждого сопоставленного элемента. Но по какой-то причине я продолжаю получать «fetch (...). Then (...). Then (...). Map is not a function»

вот полный код

import './styles.css';
import template from './templates/template.hbs';

const api = {
  key: '#',
  querySearch: '',
  pageNum: 1,
};

const refs = {
  list: document.querySelector('.gallery'),
  form: document.querySelector('#search-form'),
  input: document.querySelector('input'),
};

refs.input.addEventListener('input', catchInput);

function catchInput(event) {
  console.log(event.target.value);
  getResults(refs.input.value);
  console.log(refs.input.value);
}

function getResults(querySearch) {
  api.pageNum += 1;
  refs.list.innerHTML = '';
  const imgBlock = fetch(
    `https://pixabay.com/api/?image_type=photo&orientation=horizontal&q=${querySearch}&page=${api.pageNum}&per_page=12&key=${api.key}`,
  )
    .then(data => {
      return data.json();
    })
    .then(pic => pic.hits)
    .map(item => template(item).join(''));
  refs.list.insertAdjacentHTML('beforeend', imgBlock);
}

РУЧКИ

    <div class="photo-card">
    <img src="{{webformatURL}}" alt="{{webformatURL}}" />
    <div class="stats">
        <p class="stats-item">
            <i class="material-icons">thumb_up</i>
            {{likes}}
        </p>
        <p class="stats-item">
            <i class="material-icons">visibility</i>
            {{visibility}}
        </p>
        <p class="stats-item">
            <i class="material-icons">comment</i>
            {{comments}}
        </p>
        <p class="stats-item">
            <i class="material-icons">cloud_download</i>
            {{downloads}}
        </p>
    </div>
</div>

1 Ответ

2 голосов
/ 21 июня 2020

С помощью Promises можно делать много вещей, но map() не подходит. Однако вы можете легко переписать это:

function getResults(querySearch) {
  api.pageNum += 1;
  refs.list.innerHTML = '';

  const imgBlock = fetch(
    `https://pixabay.com/api/?image_type=photo&orientation=horizontal&q=${querySearch}&page=${api.pageNum}&per_page=12&key=${api.key}`,
  )
    .then(data => data.json())
    .then(json => {
      let imgBlock = json.hits.map(item => template(item).join(''));

      refs.list.insertAdjacentHTML('beforeend', imgBlock);
    })
}

Помните, что imgBlock является обещанием и совершенно бесполезен для insertAdjacentHTML, пока он не разрешен. Вы выполнили этот код преждевременно, он должен быть помещен в обратный вызов then.

Если вы можете использовать async, этот код действительно прост, и его намного легче понять:

async function getResults(querySearch) {
  api.pageNum += 1;
  refs.list.innerHTML = '';

  const data = await fetch(
    `https://pixabay.com/api/?image_type=photo&orientation=horizontal&q=${querySearch}&page=${api.pageNum}&per_page=12&key=${api.key}`,
  );

  let json = await data.json();
  let imgBlock = json.hits.map(item => template(item).join(''));

  refs.list.insertAdjacentHTML('beforeend', imgBlock);
}

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

...