Mongodb and Nextjs(Reactjs) carousel implementation in template not working

I am attempting to implement a carousel into an already working web page template in react.
I I have a collection in mongodb titled “image_gallery” that contains the elements: filename, caption, deviceId, copyright, order, and last_update.
the filename is the name of a picture file, the caption is a description of the picture, the deviceId is the id of a device that is in the picture, the copyright is the copyright information of the picture, the order is the order in which we want to display the images, and the last_update is the date of when the entry was last updated. I have web template for a number of devices.

I have multiple devices and they each have their own page using the same react template. This template works. However what I am attempting to do now is to implement a image carousel/slider at the bottom of the template where for a given device the pictures that I have of the device will display, and this would apply to all devices given that they all use the template for their pages.

The process that I followed was the following:
create a model in react of the collection named “image_gallery” which references another model named “Device”(it has the device information), create the carousel component, import the carousel component into the device page template,… such that for each device page we could extract the device id, and use that to query the image_gallery collection, get all the documents that had that particular id and sort them by order, then get the filenames from each one of the documents, locate the file name in my images/gallery folder(as seen in the code below) and pass the documents along with the pictures into the carousel component to be displayed at the bottom of each device page.

These are models first the “Device” model which models the collection containing device information in mongodb. Then the DeviceImageGallery model which models the “image_gallery” collection.

const mongoose = require("mongoose");

const DeviceSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    trim: true,
  },
  queryName: {
    type: String,
    required: true,
    unique: true,
    trim: true,
  },
  status: {
    type: String,
    trim: true,
  },
  implantLocation: {
    type: String,
    trim: true,
  },
  summary: {
    type: String,
    trim: true,
  },
  background: {
    type: String,
    trim: true,
  },
  videoLink: {
    type: String,
    trim: true,
  },
  fdaApprovalYear: {
    type: String,
    trim: true,
  },
  ceMarkYear: {
    type: String,
    trim: true,
  },
  firstPatientYear: {
    type: String,
    trim: true,
  },
  endOfProductionYear: {
    type: String,
    trim: true,
  },
  clinicalTrials: [{
    type: String,
    trim: true,
  }],
  elecDiameter: {
    type: String,
    trim: true,
  },
  elecLayout: {
    type: String,
    trim: true,
  },
  elecNumber: {
    type: String,
    trim: true,
  },
  elecPitch: {
    type: String,
    trim: true,
  },
  imageProcessorLocation: {
    type: String,
    trim: true,
  },
  numImplantedToDate: {
    type: String,
    trim: true,
  },
  researchGroupsId: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: "ResearchGroup",
    required: true,
  }],
  commercialPartnersId: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: "Company",
    required: true,
  }],
  lastUpdate: {
    type: mongoose.Schema.Types.Date,
  },
  authorId: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Person"
    }
  ],
  verifiedId: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Person"
    }
  ],
}, { collection: "devices" });

module.exports =
  mongoose.models.Device || mongoose.model("Device", DeviceSchema);

here is the Device image gallery model:

const mongoose= require("mongoose");

const DeviceImageGallerySchema=new mongoose.Schema({
    filename:{
        type: String,
        required: true,
    },
    caption:{
        type: String,

    },
    copyright:{
        type: String,
    },
    order:{
        type: String,
        required: true,
    },
    lastupdate:{
        type: mongoose.Schema.Types.Date,
    },
    deviceId:[{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Device"
    }],
},{collection:"image_gallery"});

module.exports= mongoose.models.DeviceImageGallery || mongoose.model("DeviceImageGallery",DeviceImageGallerySchema);

Both of these are not returning any errors. So I created the carousel component naming it DeviceCarousel.js here it is :

import React, { Intl } from "react";
import Carousel from "react-multi-carousel";

const DeviceCarousel = ({ deviceImages }) => {
  const responsive = {
    superLargeDesktop: {
      // the naming can be any, depends on you.
      breakpoint: { max: 4000, min: 3000 },
      items: 5,
    },
    desktop: {
      breakpoint: { max: 2999, min: 1024 },
      items: 3,
    },
    tablet: {
      breakpoint: { max: 1023, min: 464 },
      items: 2,
    },
    mobile: {
      breakpoint: { max: 463, min: 0 },
      items: 1,
    },
  };

  return (
    <div id='news'>
      <div className='container'>
        <h1>News &amp; Articles</h1>
        <Carousel responsive={responsive}>
          {deviceImages.map((deviceimage) => {
              const imagepath =`/images/gallery/${deviceimage.filename}.jpg`;
            return (
              <div className='carouselItem'>
                  <img src={deviceimage.img} alt='Image' />
                  <div className='caption'>
                    <div className='caption-inner'>
                      <h4 className='no-bar'>{deviceimage.caption}</h4>
                      <h5 className='no-bar'>
                        {article.copyright} 
                      </h5>
                    </div>
                  </div>
                
              </div>
            );
          })}
        </Carousel>
      </div>
    </div>
  );
};

export default DeviceCarousel;

finally I tried to implement it into my already working template for device pages here it is:

import Navbar from "../../components/Header";
import Footer from "../../components/Footer";
import ArticleInfo from "../../components/ArticleInfo";

import dynamic from 'next/dynamic';
import CompanyLink from "../../components/crossLinks/companyLink";
import ResearchGroupLink from "../../components/crossLinks/researchGroupLink";
const ImageLink = dynamic(() => import("../../components/crossLinks/imageLink"), {ssr: false});
const PublicationLink = dynamic(() => import("../../components/crossLinks/publicationLink"), {ssr: false});

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBrain, faClock, faCheckCircle, faTimesCircle, 
         faHospitalUser, faAward, faBan, faUsers } from "@fortawesome/free-solid-svg-icons";

import Device from "../../models/Device";
import Company from "../../models/Company";
import ResearchGroup from "../../models/ResearchGroup";
import University from "../../models/University";
import Person from "../../models/Person";

import DeviceImageGallery from "../../models/DeviceImageGallery";
import DeviceCarousel from "../../components/devices/DeviceCarousel";

import dbConnect from "../../utils/dbConnect";
import Error from "next/error";
import axios from "axios";
import React, { useState, useEffect } from "react";



function getArticles(name) {
  let nameArr = name.split(" ");
  let queryString = "";
  nameArr.forEach(function (item, index) {
    queryString += item;
    if (index !== nameArr.length - 1) {
      queryString += "%20";
    }
  });
  const URL = `https://api.zotero.org/groups/2527936/items/top/?q=${queryString}`;
  return axios.get(URL, {
    headers: { "Zotero-API-Version": "3" },
  });
}

const DeviceTemplate = ({ errorCode, data,}) => {
  if (errorCode) {
    return <Error statusCode={errorCode} />;
  }
  const deviceInfo = JSON.parse(data);
  deviceInfo.researchGroupsId = JSON.parse(deviceInfo.researchGroupsId);
  deviceInfo.commercialPartnersId = JSON.parse(deviceInfo.commercialPartnersId);
  deviceInfo.authorId = JSON.parse(deviceInfo.authorId);
  deviceInfo.verifiedId = JSON.parse(deviceInfo.verifiedId);

  const [articles, setArticles] = useState([]);
  useEffect(() => {
    getArticles(name).then(function (result) {
      setArticles(result.data);
    });
  }, []);

  const {
    name,
    queryName,
    researchGroupsId,
    commercialPartnersId,
    status,
    implantLocation,
    numImplantedToDate,
    summary,
    background,
    videoLink,
    clinicalTrials,
    imageProcessorLocation,
    elecNumber,
    elecLayout,
    elecDiameter,
    elecPitch,
    firstPatientYear,
    fdaApprovalYear,
    ceMarkYear,
    endOfProductionYear,
    lastUpdate,
    authorId,
    verifiedId
  } = deviceInfo;

  const imagePath = `/images/logos/devices/${queryName}.jpg`;
  

  return (
    <div>
      <Navbar scrollEffect={true} />
      <div id='device-profile'>
        <div className='container'>
          <div className='row mb-4'>
            <div className='col-xs-3 col-sm-3 col-md-3'>
              <ImageLink 
                id='device-logo' 
                className='border-image'
                src={imagePath} 
                alternativeImage="/images/logos/devices/device.png" 
              />
            </div>
            <div id='device-info' class='col-xs-9 col-sm-9 col-md-9'>
              <h2>{name}</h2>
              { implantLocation && (
                <p><FontAwesomeIcon icon={faBrain} size='1x' alt='implant location' />{implantLocation}</p>
              )}
              { numImplantedToDate && (
                <p><FontAwesomeIcon icon={faUsers} size='1x' alt='implant location' />{numImplantedToDate} implanted</p>
              )}              
              { status == "active" && (
                <p><FontAwesomeIcon icon={faCheckCircle} size='1x' alt='active' />active</p>
              )}
              { status == "inactive" && (
                <p><FontAwesomeIcon icon={faTimesCircle} size='1x' alt='inactive' />inactive</p>
              )}
            </div>
          </div>

          { summary && (
            <div className='row mb-3'>
              <p>{summary}</p>
            </div>
          )}

          { commercialPartnersId.length !== 0 && (
            <div className='row mb-3'>
              <h3>Commercial Partners {queryName} </h3>
              <ul className='cross-links d-flex flex-wrap p-1'>
                {commercialPartnersId.map(partner => (
                  <CompanyLink
                    name={partner.name}
                    queryName={partner.queryName}
                    city={partner.city}
                    country={partner.country} />
                  ))
                }
              </ul>
            </div>
          )}

          { researchGroupsId.length !== 0 && (
            <div className='row mb-3'>
              <h3>Academic Collaborators</h3>
              <ul className='cross-links d-flex flex-wrap p-1'>
                {researchGroupsId.map(partner => (
                  <ResearchGroupLink
                    name={partner.name}
                    queryName={partner.queryName}
                    university={partner.universityId && partner.universityId.name} />
                  ))
                }
              </ul>
            </div>
          )}


          { (firstPatientYear || fdaApprovalYear || ceMarkYear || endOfProductionYear) && (
            <div className='row mb-3'>
              <h3>Milestones</h3>
              <ul className='milestones'>
                { firstPatientYear && (
                  <li><FontAwesomeIcon icon={faHospitalUser} size='1x' alt='first patient'/>{firstPatientYear}: First patient implanted</li>
                )}
                { ceMarkYear && (
                  <li><FontAwesomeIcon icon={faAward} size='1x' alt='CE mark approval'/>{ceMarkYear}: CE mark approval</li>
                )}
                { fdaApprovalYear && (
                  <li><FontAwesomeIcon icon={faAward} size='1x' alt='FDA approval'/>{fdaApprovalYear}: FDA approval</li>
                )}
                { endOfProductionYear && (
                  <li><FontAwesomeIcon icon={faBan} size='1x' alt='End of production'/>{endOfProductionYear}: End of production</li>
                )}
              </ul>
            </div>
          )}

          { (background || videoLink) && (
            <div className='row mb-4'>
              <h3>Background</h3>
              <p dangerouslySetInnerHTML={{ __html: background }} />
              <div dangerouslySetInnerHTML={{ __html: videoLink }} />
            </div>
          )}

          { (elecNumber || elecLayout || elecDiameter || elecPitch || imageProcessorLocation) && (
            <div className='row mb-3'>
              <h3>Device Specifications</h3>
              <ul>
                { elecNumber && (
                  <li>Number of electrodes: {elecNumber}</li>
                )}
                { elecLayout && (
                  <li>Electrode layout: {elecLayout}</li>
                )}
                { elecDiameter && (
                  <li>Electrode diameter: {elecDiameter} μm</li>
                )}
                { elecPitch && (
                  <li>Electrode pitch: {elecPitch} μm</li>
                )}
                { imageProcessorLocation && (
                  <li>Image processor location: {imageProcessorLocation}</li>
                )}
              </ul>
            </div>
          )}

          { clinicalTrials.length !== 0 && (
            <div className='row mb-3'>
              <h3>Clinical Trials</h3>
              <ul>
                { clinicalTrials.map(item => (
                  <li><a href={`https://clinicaltrials.gov/ct2/show/${item}`} target='_blank'>{item}</a></li>
                ))}
              </ul>
            </div>
          )}

          {articles.length !== 0 && (
            <div className='row mb-3'>
              <h3>Selected Publications </h3>
              <ul className='cross-links'>
              {articles.map(article => (
                <PublicationLink
                  authors={article.data.creators}
                  title={article.data.title}
                  date={article.data.date}
                  journal={article.data.publicationTitle}
                  conference={article.data.proceedingsTitle}
                  doi={article.data.DOI}
                  issue={article.data.issue}
                  volume={article.data.volume}
                  pages={article.data.pages}
                  type={article.data.itemType} />
                ))
              }
              </ul>
            </div>
          )}

          <div className='row mb-4'>
            <ArticleInfo lastUpdate={lastUpdate} authorId={authorId} verifiedId={verifiedId}/>
            <DeviceImageGallery deviceImages={deviceImages} />
          </div>
          

        </div>
      </div>
      <Footer />
    </div>
  );
};

export async function getServerSideProps({ query: { deviceName } }) {
  dbConnect();
  const deviceResult = await Device.findOne({
    queryName: deviceName,
	})
    .populate({ path: "researchGroupsId", model: ResearchGroup,
                select: "name university queryName",
                populate: { path: "university", model: University, select: "name" }})
    .populate({ path: "commercialPartnersId", model: Company, 
                select: "name queryName city country yearFounded yearDissolved" })
    .populate({ path: "authorId", model: Person, 
                select: "firstName preferredName lastName queryName researchGroupId",
                populate: { path: "researchGroupId", model: ResearchGroup, select: "universityId",
                            populate: { path: "universityId", model: University, select: "name" } } })
    .populate({ path: "verifiedId", model: Person, 
                select: "firstName preferredName lastName queryName researchGroupId",
                populate: { path: "researchGroupId", model: ResearchGroup, select: "universityId",
                            populate: { path: "universityId", model: University, select: "name" } } });
  const errorCode = deviceResult ? false : 400;
  deviceResult.researchGroupsId = JSON.stringify(deviceResult.researchGroupsId);
  deviceResult.commercialPartnersId = JSON.stringify(deviceResult.commercialPartnersId);
  deviceResult.authorId = JSON.stringify(deviceResult.authorId);
  deviceResult.verifiedId = JSON.stringify(deviceResult.verifiedId);
  deviceResult.lastUpdate = JSON.stringify(deviceResult.lastUpdate);
  //the code that we changed is below
  deviceResult._id=JSON.stringify(deviceResult._id);
  
  const deviceImages = await DeviceImageGallery.find({deviceId: deviceResult._id}).sort({ order: 1 });
  //
  return {
    props: { errorCode: errorCode, data: JSON.stringify(deviceResult) },
  };
}

export default DeviceTemplate;

I am getting getting an error saying that deviceImages is not defined when I am implementing it to the device page template. In particular when I am passing in the line of code: <Device Carousel deviceImages={deviceImages} >
I cant seem to find the error that I am committing? or is there some sort of error in my carousel component? I declared the above in the async function but it does not seem to be working, Any ideas on what things I am doing wrong?

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.