Как отфильтровать массив, игнорируя элементы с неопределенными свойствами?

Я пытаюсь сопоставить URL-адреса изображений с компонентом аватара. Данные, которые я использую, поступают из API Google Книг. Ресурс данных представляет собой массив объектов (книг). У некоторых объектов отсутствуют значения для поля «миниатюра», на которое я ориентируюсь.

Я хочу ИГНОРИРОВАТЬ эти объекты, если они не имеют значения для «миниатюры», и продолжить отображение через массив.

Я использую React Native и Expo.

Я пробовал различные методы, упомянутые в Stack Overflow, включая array.filter() с логикой для моих данных до array.map(). Ни одно из рекомендованных решений не сработало.

Ошибка, которую я получаю:

TypeError: TypeError: undefined не является объектом (оценка «url.volumeInfo.imageLink.thumbnail»)

Похоже, я даже не могу иметь этот путь внутри оператора «если», что для меня странно, потому что даже если это значение не определено, какое это имеет значение?

renderCategory() {

        if (this.props.adventure.payload[0]) {
        const fetched_Book = this.props.adventure.payload;
        const filteredThumbnails = fetched_Book.filter(url =>{

           // The console log below shows 4 urls before it fails)
            console.log('URL', url.volumeInfo.imageLinks.thumbnail)

            if(typeof url.volumeInfo.imageLinks.thumbnail === "undefined"){
                return false
            }
            else return true;
            })
        const allThumbnails= filteredThumbnails.map(book => book.volumeInfo.imageLinks.thumbnail);
        return (
            <>
                <View style={styles.thumbnailContainer}>
                    {
                        allThumbnails.map((l, i) =>
                            <Avatar
                                key={i}
                                size="large"
                                source={{ uri: l }}
                                style={styles.thumbNail}
                                onPress={() => this.onSelectedBook(fetched_Book, i)}
                            />
                        )
                    }
                </View>

            </>
        )
    }
    else return ''
    }

Ожидаемый результат — новый отфильтрованный массив объектов, который затем можно сопоставить с моим компонентом аватара.


person jmedran    schedule 22.07.2019    source источник
comment
Скорее всего, поле imageLink или volumeInfo в каком-то случае не существует. Итак, вы звоните unknown.thumbnail, что дает вам ошибку   -  person chakwok    schedule 22.07.2019
comment
@Андык. Спасибо за комментарий! Вы правы, проверка наличия свойства imageLinks решила мою проблему. У вас есть рекомендации по масштабированию? Я заметил, что API Google Книг довольно изменчив со случайными случаями отсутствия данных. Кажется, я не могу эффективно проверять каждый экземпляр пропущенного значения на всем протяжении большого объекта.   -  person jmedran    schedule 22.07.2019
comment
Есть несколько способов сделать так. Если у вас нет объектов с вложенностью 5+, я думаю, можно просто проверить if(url.volume.imageLink && url.volume.imageLink.thumbnail)   -  person chakwok    schedule 22.07.2019
comment
@Андык. Я ценю помощь и полезную ссылку   -  person jmedran    schedule 22.07.2019
comment
Я рад, что это помогает. Не забудьте проголосовать за ответ, который вы считаете полезным, и проголосовать за некачественный, чтобы люди, которые посетили его позже, могли легко найти полезную информацию.   -  person chakwok    schedule 22.07.2019


Ответы (1)


Эта ошибка означает, что некоторая часть пути к миниатюре не существует, поэтому вам нужно проверить, существует ли каждая часть этого пути:

const filteredThumbnails = fetched_Book
  .filter(url => !!url && !!url.volumeInfo && !!url.volumeInfo.imageLinks && typeof url.volumeInfo.imageLinks.thumbnail === 'undefined')
person Xesenix    schedule 22.07.2019