travis-r6s / gridsome-plugin-flexsearch

Add lightning fast search to Gridsome with FlexSearch
24 stars 7 forks source link

Cannot read property 'map' of undefined #73

Closed Samii-Noden-Poli closed 2 years ago

Samii-Noden-Poli commented 2 years ago

I'm not sure what I'm doing wrong here - I'm trying to transform the schema to enable searching in nested data structures but I just keep getting the above error.

gridsome.config.js image

error message received on 'gridsome develop' image

What haven't I done right?

travis-r6s commented 2 years ago

If you log collection, does it return an array of authors? If so, could you paste what it does log?

Samii-Noden-Poli commented 2 years ago

I'm not sure I'm following, sorry. Log it in what way?

travis-r6s commented 2 years ago

Something like this:

transform: (collection) => {
    console.log(collection)
    return {
        ...collection,
        authors: collection.authors.map(author => author.name)
    }
}
Samii-Noden-Poli commented 2 years ago

Ah I see what you mean - the above code logs the whole object but only for one post(?). So it's returning everything from title to featuredMedia etc

The below is a test post with the error message at the bottom.

[Object: null prototype] { id: '7442', title: 'Yoast Post', slug: 'yoast-post', path: '/resources/news/yoast-post/', featuredMedia: [Object: null prototype] { id: '7560', date: '2021-07-29T13:50:17', dateGmt: '2021-07-29T13:50:17', guid: '/removedorprivacyreasons/', modified: '2021-07-29T13:50:31', modifiedGmt: '2021-07-29T13:50:31', slug: 'test-featured-image', status: 'inherit', type: 'attachment', link: '/removedorprivacyreasons/', title: 'test-featured-image', author: [Object: null prototype] { id: '1', name: 'Samii Noden', url: '/removedorprivacyreasons/', description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lacinia at quis risus sed vulputate. Nunc pulvinar sapien et ligula ullamcorper. Ut sem nulla pharetra diam sit. Massa sapien faucibus et molestie ac. Lacus laoreet non curabitur gravida arcu. Vitae justo eget magna fermentum iaculis eu. Odio facilisis mauris sit amet massa vitae tortor. Eget nunc scelerisque viverra mauris in aliquam sem fringilla. Nulla posuere sollicitudin aliquam ultrices sagittis orci a. Leo a diam sollicitudin tempor id eu nisl nunc. Volutpat commodo sed egestas egestas fringilla phasellus faucibus scelerisque.', link: '/removedorprivacyreasons/', slug: 'samiinoden', avatarUrls: [Object: null prototype], yoastHead: '\n' + 'Author | Samii Noden\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '', title: 'Samii Noden', avatars: [Object: null prototype], path: '/resources/author/samiinoden/' }, commentStatus: 'open', pingStatus: 'closed', template: '', yoastHead: '\n' + '/<em>removedorprivacyreasons</em>/\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\n' + '\t\n' + '\t\n' + '\n' + '\n' +
'', description: /removedorprivacyreasons/ caption: '', altText: 'Test featured image', mediaType: 'image', mimeType: 'image/png', mediaDetails: [Object: null prototype] { width: 545, height: 254, file: '2021/07/test-featured-image.png', sizes: [Object: null prototype], imageMeta: [Object: null prototype] }, post: 7542, sourceUrl: /removedorprivacyreasons/ }, acf: [Object: null prototype] { ukHrefLang: 'Uk href lang test', usHrefLang: '', heroTitle: 'Hero title test', heroText: '', readTime: '2', videoUrl: '', transcript: '', mostPopular: [ 'true' ] }, type: 'post', categories: [ [Object: null prototype] { id: '7', title: 'News', slug: 'news', content: '', count: 3, path: '/resources/category/news/' } ], tags: [ [Object: null prototype] { id: '37', title: 'News', slug: 'news', content: '', count: 4, path: '/resources/tag/news/' }, [Object: null prototype] { id: '38', title: 'Yoast', slug: 'yoast', content: '', count: 1, path: '/resources/tag/yoast/' } ], date: '2021-07-01T09:47:24', excerpt: '

Unique yoast data to find it easier

\n', content: '

Unique yoast data to find it easier

\n' }

TypeError: gridsome.config.js: Cannot read property 'map' of undefined (132:45)

130 | return { 131 | ...collection,

132 | authors: collection.authors.map(author => author.name) | ^ 133 | } 134 | } 135 |

travis-r6s commented 2 years ago

Okay - so that shows author as an object, not an array? So you can't run an array method (like map) on an object...

Samii-Noden-Poli commented 2 years ago

Ah of course - so will I not be able to search on categories, tags, authors or acf? Or is there another way to include child objects within the parent object?

travis-r6s commented 2 years ago

You should be able to, just specifying 'author' in the search fields should automatically fetch the nested author object, and index it...

Samii-Noden-Poli commented 2 years ago

Hmmm - it's not working. It turns out that categories and tags are arrays so they are fine using the map method. I just can't search by author or advanced custom fields - they're both definitely in there

searchFields: [ 'title', 'tags', 'type', 'author', 'category', 'excerpt', 'content', 'slug', 'path', 'sector', 'acf', ],

travis-r6s commented 2 years ago

Hmm, okay - I'll take a look into this when I get a chance.

Incidentally, you could just return the authors name by using the function option - I.e. author: collection.author.name

Samii-Noden-Poli commented 2 years ago

I have no idea why I didn't think of that in the first place - that works for me and I'm happy to take that as a solution.

Thanks so much for your help!

travis-r6s commented 2 years ago

Great - I'll keep this open to remind me to check why it doesn't index nested objects, although it may be a flexsearch config needed.

travis-r6s commented 2 years ago

Think I may have a solution for this - like arrays, nested objects can be stringified, so Flexsearch will then parse that data as a string.

@Samii-Noden If you have time, would you be able to test out this fix (v2.0.2) to see if it works for you?

Samii-Noden-Poli commented 2 years ago

Yeah I can give it a test - so would it be a case of just specifying 'authors' in the searchFields array without having to do author: collection.author.name in the collection?

travis-r6s commented 2 years ago

Great, thanks 🙂 yes, that is correct...

Although bear in mind it will index every single field under author, so you may still want to filter out some fields by returning an object with the transform function - I.e.

transform: collection => ({
    ...collection,
    author: {
        name: collection.author.name,
        bio: collection.author.bio
    }
})
Samii-Noden-Poli commented 2 years ago

Thank you - that appears to work!