Decoding base64 img in react getting error

32 Views Asked by At

In this project I created a custom input field which can bold the selected text and insert the image between text or between 2 lines of text and I am saving this data in the form of buffer/innerHTML to the mongoDB database.

But when I try to fetch the data text are getting fetched correctly but img which is converted in encoded not getting decoded properly here the demo i my image is getting displayed when i am fetching data

Please provide a solution to display the the img properly decoded.

This is how my img is displyed

this is my consultingdetiled.js page which has front end code

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Boldicon from '../Assests/bold.png';
import Pictureicon from '../Assests/picture.png';
import Linkicon from '../Assests/link.png';

const Consultingdetailed = () => {
    const [title, setTitle] = useState("");
    const [content, setContent] = useState("");
    const [errors, setErrors] = useState({});
    const [consultingData, setConsultingData] = useState([]);

    const handleTitleChange = (e) => {
        setTitle(e.target.value);
        setErrors(prevErrors => ({ ...prevErrors, title: '' })); // Clear title error on change
    };

    const handleSubmit = async (e) => {
        e.preventDefault();

        // Validation
        const errors = {};
        if (title.trim() === '') {
            errors.title = "Title should not be blank";
        }
        if (Object.keys(errors).length > 0) {
            setErrors(errors);
            return;
        }

        // Get content from content-editor div
        const contentDiv = document.querySelector('.content-editor');
        const contentRaw = contentDiv.innerHTML;

        try {
            const response = await axios.post('http://localhost:8080/api/v1/consulting-detailed/add-consult-detailed', {
                title,
                content: contentRaw
            });
            if (response.status === 201) {
                console.log("Data saved successfully!");
                // Clear form inputs after successful submission
                setTitle("");
                setContent(""); // Clear content as well
                fetchConsultingData(); // Fetch updated consulting data after submission
            } else {
                console.error("Failed to save data");
            }
        } catch (error) {
            console.error("Error:", error);
        }
    };

    const handleInsertImgClick = () => {
        // Programmatically trigger file input click
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = 'image/*';
        fileInput.onchange = (e) => {
            const file = e.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const img = document.createElement('img');
                    img.src = e.target.result;
                    // Insert image at current caret position
                    document.execCommand('insertHTML', false, img.outerHTML);
                };
                reader.readAsDataURL(file);
            }
        };
        fileInput.click();
    };

    useEffect(() => {
        fetchConsultingData(); // Fetch consulting data when component mounts
    }, []);

    const fetchConsultingData = async () => {
        try {
            const response = await axios.get('http://localhost:8080/api/v1/consulting-detailed/fetch-consult-detailed');
            setConsultingData(response.data);
        } catch (error) {
            console.error('Error fetching consulting data:', error);
        }
    };

    return (
        <div>
            <h1>Consulting Detailed Page</h1>
            <form onSubmit={handleSubmit}>
                            
                <div className='inputcard2'>
                    <div className='formdata'>
                        <label>Title</label>
                        <input type='text' id='title' value={title} onChange={handleTitleChange} placeholder="Enter Title" />
                        <div className="part2">
                            <span className="errorclass" id="errorname">{errors.title}</span>
                        </div>
                    </div>
                    <div className='formdata2'>
                        <label>Title</label>
                        <div className="form-controls">
                            <div className='controls-icon' onClick={() => document.execCommand('bold', false, null)} style={{borderRight: '1px solid black'}}>
                                <img src={Boldicon} alt='Bold icon' className='icon2' style={{height: 15, width: 15}}/>
                            </div>
                            <div className='controls-icon' onClick={handleInsertImgClick} style={{borderRight: '1px solid black'}}>
                                <img src={Pictureicon} alt='Picture icon' className='icon2'/>
                            </div>
                            {/* <div className='controls-icon'>
                                <img src={Linkicon} alt='Link icon' className='icon2'/>
                            </div> */}
                        </div>
                        <div className="content-editor" contentEditable={true} dangerouslySetInnerHTML={{ __html: content }} />
                        <div className="part2">
                            <span className="errorclass" id="errorname">{errors.content}</span>
                        </div>
                    </div>
                    <div className='formbutton'>
                        <button>Submit</button>
                    </div>
                </div>
            </form>

            {/* Consulting data table */}
            <div>
                <h2>Consulting Data</h2>
                <table>
                    <thead>
                        <tr>
                            <th>Title</th>
                            <th>Content</th>
                        </tr>
                    </thead>
                    <tbody>
                        {consultingData.map((item, index) => (
                            <tr key={index}>
                                <td>{item.title}</td>
                                <td dangerouslySetInnerHTML={{ __html: item.content }} />
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        </div>
    );
};

export default Consultingdetailed;

and

this is my consultingdetsiledController.js

const axios = require('axios');
const consultingdetailedModel = require("../models/consultingdetailedmodel");

const addConsultingDetailed = async (req, res) => {
    try {
        const { title, content } = req.body;
        
        // Function to convert image URLs to buffer
        const getImageBuffer = async (url) => {
            try {
                const response = await axios.get(url, { responseType: 'arraybuffer' });
                return response.data;
            } catch (error) {
                console.error('Error fetching image:', error);
                return null;
            }
        };

        // Convert content to buffer
        let contentBuffers = [];
        const contentElements = content.split(/(<img[^>]+>)/); // Split content by <img> tags
        for (let element of contentElements) {
            if (element.startsWith('<img')) {
                // If element is an image tag, fetch and convert to buffer
                const srcRegex = /src="([^"]+)"/;
                const match = element.match(srcRegex);
                if (match && match[1]) {
                    const imageUrl = match[1];
                    const imageBuffer = await getImageBuffer(imageUrl);
                    if (imageBuffer) {
                        contentBuffers.push(imageBuffer);
                    }
                }
            } else {
                // If element is text, convert to buffer
                contentBuffers.push(Buffer.from(element, 'utf-8'));
            }
        }

        // Concatenate all content buffers
        const concatenatedBuffer = Buffer.concat(contentBuffers);

        // Save to MongoDB
        const newData = new consultingdetailedModel({
            title,
            content: concatenatedBuffer
        });
        await newData.save();
        res.status(201).json({ message: 'Data Created' });
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Failed to add consulting detailed data' });
    }
};


const fetchConsultingDetailed = async (req, res) => {
    try {
        const consultingDetailedData = await consultingdetailedModel.find();
        res.status(200).json(consultingDetailedData);
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Failed to fetch consulting detailed data' });
    }
};

module.exports = { addConsultingDetailed, fetchConsultingDetailed};
0

There are 0 best solutions below