Promise Error mapping data from backend in React

Viewed 75

So what I want to do is getting an Array from my backend, which is coming from fs reading through a folder on my Server, giving back an Array with the names of the pictures in it.

Using this Array I want to map through it and creating a Picture Component for every picture.

I am getting two main errors in the console:

First:

Uncaught Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
    at throwOnInvalidObjectType (react-dom.development.js:14757:1)
    at reconcileChildFibers (react-dom.development.js:15698:1)
    at reconcileChildren (react-dom.development.js:19964:1)
    at mountIndeterminateComponent (react-dom.development.js:20996:1)
    at beginWork (react-dom.development.js:22416:1)
    at beginWork$1 (react-dom.development.js:27381:1)
    at performUnitOfWork (react-dom.development.js:26513:1)
    at workLoopSync (react-dom.development.js:26422:1)
    at renderRootSync (react-dom.development.js:26390:1)
    at recoverFromConcurrentError (react-dom.development.js:25806:1)

Second:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'useState')
    at useState (react.development.js:1620:1)
    at Collage (Collage.jsx:14:1)
    at describeNativeComponentFrame (react-dom.development.js:1089:1)
    at describeFunctionComponentFrame (react-dom.development.js:1184:1)
    at describeFiber (react-dom.development.js:1263:1)
    at getStackByFiberInDevAndProd (react-dom.development.js:1282:1)
    at createCapturedValue (react-dom.development.js:18510:1)
    at throwException (react-dom.development.js:18976:1)
    at handleError (react-dom.development.js:26267:1)
    at renderRootSync (react-dom.development.js:26393:1)

First I put in my backend code:

app.get("/api/getimages", cors(corsOptions), (req, res)  => {
    const getFiles = fs.readdir("client/public/img/collection", function (err, files) {
        if (err) {
            return console.log('Unable to scan directory: ' + err);
        } 
        console.log(files);
        res.send(files);
    });
    
    });

And here is my frontend code:

import React, { useEffect, useState } from 'react';

function Picture(props){

    return( <div className="col-lg-4 col-md-3">
        <img alt="Hi" className="collageImage img-responsive" src={"/img/" + props.name} />
    </div>
    )

}


async function Collage() {
const [loading, setLoading] = useState(true);
const [imageArray, setimageArray] = useState([]);

const getAnswer = async () => {
    const res = await fetch("http://localhost:3001/api/getimages");
    const json = await res.json();
    setimageArray(json.data);
    console.log(json);
    setLoading(false);
    
  };

  useEffect( () => {
    getAnswer();
  }, []);

if(loading === true){
    return(<div>Loading....</div>)
}else{
    return(
        <div className="imagesSection">
        <div className="container-fluid">
        <div className="row">
        {imageArray.map((image) => (<Picture 
        key = {image}
        number = {image}
        alt = {image} />)
        )}
        </div>
        </div>
        </div> 
    )
}

}


export default Collage

Thank you very much in advance!!!!!!

The best regards, Maggi

2 Answers

try this backend code

var fs = require("fs");
var https = require("https");
const http = require("http");
const express = require("express");
const app = express();
var cors = require("cors");

/*----------------------
 setting up the server 
 ----------------------*/
const host = "localhost";
const port = 8000;

app.use(cors());
app.listen(port, () =>
  console.log(`Hello world app listening on port ${port}!`)
);

app.get("/get-image", (req, res) => {
  const imageData = [
    {
      image: "testimage1.jpg",
    },
    {
      image: "testimage2.jpg",
    },
    {
      image: "testimage3.jpg",
    },
    {
      image: "testimag4.jpg",
    },
    {
      image: "testimage5.jpg",
    },
  ];
  res.send(imageData);
});

& for the front end

import React, { useEffect, useState } from "react";

function Picture(props) {
  return (
    <div className="col-lg-4 col-md-3">
      <img
        alt="Hi"
        className="collageImage img-responsive"
        src={"/img/" + props.images}
      />
    </div>
  );
}

const TestFunction = () => {
  const [loading, setLoading] = useState(true);
  const [imageArray, setimageArray] = useState([]);

  const getAnswer = async () => {
    const res = await fetch("http://localhost:8000/get-image");
    const json = await res.json();
    setimageArray(json);
    setLoading(false);
  };

  useEffect(() => {
    getAnswer();
  }, []);
  if (loading === true && imageArray.length <= 0) {
    return <div>Loading....</div>;
  } else {
    return (
      <div className="imagesSection">
        <div className="container-fluid">
          <div className="row">
            {imageArray.map((image, index) => (
              <Picture key={index} number={image} alt={image} />
            ))}
          </div>
        </div>
      </div>
    );
  }
};

export default TestFunction;

I managed to get it working. If someone in the future has the same error here is the frontend code:

import React, { useEffect, useState } from 'react';

function Picture(props){

    return( <div className="col-lg-4 col-md-3">
        <img alt="Hi" className="collageImage img-responsive" src={"/img/collection/" + props.number} />
    </div>
    )
}


function Collage() {
const [imageArray, setImageArray] = useState([]);

    useEffect(() => {
        const res = fetch("http://localhost:3001/api/getimages")
        .then((response) =>{
            if(response.ok) {
                return response.json();
            }
        
        throw new Error('Something went wrong');
    })
    .then((responseJson) => {
        setImageArray(responseJson)
      })
      .catch((error) => {
        console.log(error)
      });
      }, []);

    return(
        <div className="imagesSection">
        <div className="container-fluid">
        <div className="row">
        {imageArray.map((image) => (<Picture 
        key = {image}
        number = {image}
        alt = {image} />)
        )}
        </div>
        </div>
        </div> 
    )
}



export default Collage
Related