Как исправить «TypeError: (images || []).forEach не является функцией»

В Node.js (используется MS Bot Framework) я пытаюсь перебрать массив, содержащий несколько объектов, которые были возвращены fetch(). Он делает одну итерацию, а затем выдает ошибку.

Я уже исключил выборку узла из уравнения и использовал статический массив своих объектов. Я также попытался преобразовать в массив. Все тот же результат: TypeError: (images || []).forEach is not a function после первой итерации все прошло отлично.

Вот как это выглядит на данный момент (значения объектов сокращены для удобства чтения):

// exact copy of what fetch returns
let test = [
    {
        title: 'Power BI Desktop—Interactive Reports | Microsoft Power BI',
        link: 'https://support.office.com/',
        description: 'Create interactive reports with data',
        thumbnail: 'https://powerbi.microsoft.com/'
    }, {
        title: 'What is Power BI administration? - Power BI',
        link: 'https://support.office.com/',
        description: 'Learn about the configuration of Power BI ',
        thumbnail: 'https://docs.microsoft.com/'
    }, {
        title: 'Add a PowerBI tab to Teams',
        link: 'https://support.office.com/',
        description: 'You can add a new or existing PowerBI',
        thumbnail: 'https://support.office.com/'
    }
];

let cardContent = [];
test.forEach(element => {
    logger.debug('working on: %j', element);
    let card = CardFactory.heroCard(
        element.title,
        element.description,
        element.thumbnail,
        [element.link],
        ['Open Item']
    );
    cardContent.push(card);
});

Просто для справки, вот часть моей функции выборки:

return fetch(url + question)
    .then(res => res.json())
    .then(jsonResponse => {
        return jsonResponse;
    })

Я действительно не знаю, что еще попробовать сейчас. Точно такая же настройка работала в устаревшей версии моего приложения — только с axios, но я пробовал и это.

(images || []).forEach нет нигде в коде, который вы разместили...?
CertainPerformance 09.04.2019 23:56

Если это ошибка, которую вы получаете, очевидно, что изображения верны, но не являются массивом. Возможно, стоит рассмотреть developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

jonrsharpe 09.04.2019 23:57

О какой функции извлечения вы говорите? Вы нигде не используете обещания в коде, который вы разместили.

Bergi 09.04.2019 23:57

@CertainPerformance Именно поэтому я совершенно не понимаю, откуда эта ошибка. Я немного углубился в исходный код Bot Framework, и, похоже, это ошибка в их CardFactory.

Malte 10.04.2019 11:28
Причина найдена: В документации указано, что вы можете отправлять URL-адреса изображений в виде строки. Однако они должны быть в массиве: (images || []).forEach((img: (CardImage | string)). Отсюда и пошла ошибка. К сожалению, документация по платформам для ботов местами блеклая.
Malte 10.04.2019 11:42
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
3 323
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Невозможно с уверенностью сказать, почему (images || []).forEach не является функцией, не зная, где/как определяется images, но я рискну предположить и скажу, что imagesсуществует и является объектом, а не массивом.

Попробуйте выполнить

const images = {};
images.forEach(image => console.info(image))

И вы увидите тот же результат, Uncaught TypeError: images.forEach is not a function.

Возможно, это поле images.data в объекте, который вы хотите запустить forEach.

Ответ принят как подходящий

Я запускаю ваш код, и он работает - это означает, что массив test не содержит того, что, по вашему мнению, он содержит (возможно, он содержит обещание, возвращаемое fetch() ). Используйте fetch с ключевым словом await, чтобы получить ответ, и снова используйте await, чтобы получить json (что-то вроде кода ниже — я пишу его из головы)

async function load(url, question) {
    ...
    return await (await fetch(url + question)).json()
}

...
test = await load(url, question) // this call shoud be also inside async function

Вероятно, test (или images в вашем производственном коде) определен, но не является массивом.

garrettmaring 10.04.2019 00:18

Спасибо! Оказывается, в документации MS Bot Framework есть ошибка, в которой говорится, что вы можете отправлять URL-адреса изображений в виде простой строки, хотя на самом деле они должны быть в массиве. Вы бы сказали, что лучше использовать await даже перед fetch()? Я никогда этого не делал (и нигде раньше этого не видел), и это работает просто отлично. Все остальное использует await, я просто никогда не думал использовать его перед fetch() в асинхронной функции.

Malte 10.04.2019 11:48

По моему мнению, await хорошо справляется с обещаниями ведьм (например, возвращаемыми fetch()).

Kamil Kiełczewski 10.04.2019 18:12

Другие вопросы по теме