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};