0

I'm on a react/node website project. Pretty simple website with a crud. My crud worked but my pictures doesn't appears (they are upload on a folder public/uploads/news/ and their path is save in mongoDb) For my news I can see the title, message, date but the picture is broken and I've only the alt. When I go to the console and go on the element, the patch is OK "c:/users/......... /public/uploads/news/nameofmypicture.jpg". I just got an error message "not allowed to load local resources"

import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { dateParser, isEmpty } from "../../../general/utils/Utils";
import { updateNews } from "../../../../store/actions/news.actions";
import DeleteCard from "./DeleteCard";
import Loader from "../../../general/utils/Loading";

const Card = ({ news }) => {
    const [isLoading, setIsLoading] = useState(true);
    const [isUpdated, setIsUpdated] = useState(false);
    const [textUpdate, setTextUpdate] = useState(null);
    const newsData = useSelector((state) => state.newsReducer);
    const dispatch = useDispatch();

    const updateItem = () => {
        if (textUpdate) {
            dispatch(updateNews(news._id, textUpdate));
        }
        setIsUpdated(false);
    };

    useEffect(() => {
        !isEmpty(newsData[0]) && setIsLoading(false);
    }, [newsData]);

    return (
        <li className="card-container" key={news._id}>
            {isLoading ? (
                <Loader />
            ) : (
                <>
                    <div className="card-right">
                        <div className="card-header">
                        {isUpdated === false && <h3>{news.title}</h3>}
                        {isUpdated && (
                            <div className="update-title">
                                <textarea
                                    defaultValue={news.title}
                                    onChange={(e) => setTextUpdate(e.target.value)}
                                />
                            </div>
                        )}
                            <span>{dateParser(news.createdAt)}</span>
                        </div>
                        {isUpdated === false && <p>{news.message}</p>}
                        {isUpdated && (
                            <div className="update-post">
                                <textarea
                                    defaultValue={news.message}
                                    onChange={(e) => setTextUpdate(e.target.value)}
                                />
                                <div className="button-container">
                                    <button className="btn btn-success" onClick={updateItem}>
                                        Valider modification
                                    </button>
                                </div>
                            </div>
                        )}
                        {news.picture && (
                            <img src={news.picture} alt="card-pic" className="card-pic" />
                        )}
                        {news.video && (
                            <iframe
                                width="500"
                                height="300"
                                src={news.video}
                                frameBorder="0"
                                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                                allowFullScreen
                                title={news._id}
                            ></iframe>
                        )}
                        <div className="button-container">
                            <button className="btn btn-primary" onClick={() => setIsUpdated(!isUpdated)}>Edit</button>
                            <DeleteCard id={news._id} />
                        </div>
                    </div>
                </>
            )}
        </li>
    );
};

export default Card;

If someone wants the full code https://github.com/macath/AJC-modelism If you have more questions, ask me. I'm on this problem since 4 days, I really don't understand why it's don't work. I specify that this project will be put online so I need a valid solution on a server and not only local

Ps : sorry for my English I'm French

Macath
  • 1
  • 1
  • 1
    The images cannot have absolute paths to your file system...They need to be served by the Web Server and need to have URLs to identify and load them – Siddharth Seth Feb 08 '22 at 11:31

3 Answers3

0

please check this answer

How to upload, display and save images using node.js and express

Keigo Igarashi
  • 113
  • 1
  • 1
  • 13
0

Thanks @Rolland Costomarob & @Siddharth Seth I think the problem is that, i use multer to upload my pictures and i think i don't use it correctly.

const router = require('express').Router();
const newsController = require('../controllers/news.controller');

const multer = require('multer');
const imageStorage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, './client/public/uploads/')
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
        cb(null, 'file-' + uniqueSuffix + '.jpg')
    }
});
const upload = multer({
    limits: {
        fileSize: 10000000
    },
    fileFilter: (req, file, cb) => {
        if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg') {
          cb(null, true);
        }
        else {
          cb(new multer.MulterError('mauvais format de document'));
        }
      },
    storage: imageStorage
});

router.get('/', newsController.readNews);
router.post('/', upload.single('file'), newsController.createNews);
router.put('/:id', newsController.updateNews);
router.delete('/:id', newsController.deleteNews);

module.exports = router;

If you have the solution, you just save my life

Macath
  • 1
  • 1
0

The problem is solve. In my news.controller i replace

picture: req.file.path

by

picture: req.file.filename

In my card.js i replace

img src={news.picture}

by

<img src={`${window.location.origin}/uploads/${news.picture}`}

thanks for your help

Macath
  • 1
  • 1