Reputation: 21
So... I've been creating this website from scratch and now i'm integrating it with prismic but i keep getting this error in the terminal: TypeError: Cannot read properties of undefined (reading 'forEach').
The consequence of this error is that the local version of this website doesn't seem to load at all.
I don't really know what is wrong with my code so i'll leave it down for you to check.
require('dotenv').config();
const fetch = require('node-fetch');
const path = require('path');
const express = require('express');
const app = express();
const port = process.env.PORT || 8005;
const Prismic = require('@prismicio/client');
const PrismicH = require('@prismicio/helpers');
// Initialize the prismic.io api
const initApi = (req) => {
return Prismic.createClient(process.env.PRISMIC_ENDPOINT, {
accessToken: process.env.PRISMIC_ACCESS_TOKEN,
req,
fetch,
});
};
// Link Resolver
const HandleLinkResolver = (doc) => {
// Define the url depending on the document type
// if (doc.type === 'page') {
// return '/page/' + doc.uid;
// } else if (doc.type === 'blog_post') {
// return '/blog/' + doc.uid;
// }
// Default to homepage
return '/';
};
// Middleware to inject prismic context
app.use((req, res, next) => {
res.locals.ctx = {
endpoint: process.env.PRISMIC_ENDPOINT,
linkResolver: HandleLinkResolver,
};
res.locals.PrismicH = PrismicH;
next();
});
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));
app.locals.basedir = app.get('views');
const handleRequest = async (api) => {
const [meta, home, about, { results: collection }] = await Promise.all([
api.getSingle('meta'),
api.getSingle('home'),
api.getSingle('about'),
api.query(Prismic.Predicates.at('document.type', 'collection'), {
fetchLinks: 'product.image',
}),
]);
const assets = [];
home.data.gallery.forEach((item) => {
assets.push(item.image.url);
});
about.data.gallery.forEach((item) => {
assets.push(item.image.url);
});
about.data.body.forEach((section) => {
if (section.slice_type === 'gallery') {
section.items.forEach((item) => {
assets.push(item.image.url);
});
}
});
collection.forEach((collection) => {
collection.data.products.forEach((item) => {
assets.push(item.products_product.data.image.url);
});
});
return {
assets,
meta,
home,
collections,
about,
};
};
app.get('/', async (req, res) => {
const api = await initApi(req);
const defaults = await handleRequest(api);
res.render('pages/home', {
...defaults,
});
});
app.get('/about', async (req, res) => {
const api = await initApi(req);
const defaults = await handleRequest(api);
res.render('pages/about', {
...defaults,
});
});
app.get('/collection', async (req, res) => {
const api = await initApi(req);
const defaults = await handleRequest(api);
res.render('pages/collection', {
...defaults,
});
});
app.get('/detail/:uid', async (req, res) => {
const api = await initApi(req);
const defaults = await handleRequest(api);
const product = await api.getByUID('product', req.params.uid, {
fetchLinks: 'collection.title',
});
res.render('pages/detail', {
...defaults,
product,
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
Upvotes: 0
Views: 1872
Reputation: 241
Maybe you can check its data type before looping.
if (typeof collection !== "undefined" ) {
collection.forEach((item) => {
});
}
I spot you using the same variable when loop the collection. You cannot use same name, it should be different name to represent the object/item in the collection
collection.forEach((collection) => {
Upvotes: 1