How to display a image from src folder in react app with axios - node.js

I'm trying to display many images from my src folder in local react app on a component with axios but i don't know what i have to do to works. If i need to use node.js to do that, show me how please.
Axios code:
I would have to back 3 folders to get in src folder, from this component.
async componentDidMount() { const response = await Axios.get('src/image/'); }
React component's code:
And to show this images i'm using react-slick to render a banner.
<Slider { ...settings }> { response.map((image) => { return ( <img key="" src={image} /> ) })} </Slider>

Related

How to map dynamic routes to components outside pages folder in a NextJs multi tenant application

I am following this template here to create a Multi-tenant application using NextJS.
However, I am stucked at how to properly resolve the routing of the pages.
My pages folder is structured in this manner
pages/
_sites/[site]
[path.jsx]
index.jsx
I have the routing logic inside[path.jsx] file above
I have moved all my components from the pages folder to another folder called components.
Now, when a user visits for example james.mydomain.com/blog I wish to load the blog component from the components folder.
How can that be neatly done without too much hardcoding?
Here is what I have attempted but the page only freezes without loading the component:
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Loading from "react-loading";
export default function SiteComponent(props) {
const router = useRouter();
const [component, setComponent] = useState(null);
const { path } = router.query;
const loadComponent = async (path) => {
const importedComponent = await import(`../../../src/components/${path}`);
setComponent(importedComponent.default);
}
useEffect(() => {
if (path) {
loadComponent(path);
}
}, []);
return (
component ? <component /> : <Loading color="teal" type="bubble" />
);
}
Is there a way to do this neatly without the above dynamic component loading?
I feel the above code may not even work properly on the occasion I wish to load a nested route eg. james.mydomain.com/blog/categories.
Please kindly suggest a cleaner approach.

Why React doesn't upload image to server?

I have an app using react and express on the backend and multer to manage the upload. The server side is running properly when I make tests using postman, but if trait to send an image from react the result is unexpected. In that case the file doesn't appear in the uploads folder, however with postman is immediatly.
UploadPage,jsx
const { register, handleSubmit } = useForm();
const onSubmit = async (data) => {
const formData = new FormData();
formData.append('petimage', data.petimage);
try {
const res = await axios.post('/api/petregister', formData);
console.log(res)
} catch (error) {
setError(error.response.data.error);
setTimeout(() => {
setError("");
}, 5000);
}
}
return (
<Container className="mt-5">
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Imagen de tu Mascota</Form.Label>
<Form.Control type="file"
label="Select image"
name="petimage"
{...register("petimage")}
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Container>
Google Response
The fields with name petimage are the same that I expecified in the backend and used these in the postman tests.
Edit
const store = require('../middlewares/multer');
route.post('/petregister', store.array('petimage', 12), petregister);
The last section of code is the route that is linked with the multer midleware asigned to ssave the images.
When you are making a API call to the backend, it will upload the image to the specific folder that you are defining in the backend like :
const multer = require('multer');
const upload = multer({ dest: 'folder path' });
I think you are getting results unexpected because the name for the image you are giving in formData formData.append('petimage', data.petimage); i.e petimage, it should be the same in the multer fileupload method. You haven't shared the backend code. So, I'm hoping that it may be like this:
var fileUpload = upload.single('petimage'); when the name is the same it will work fine.
If the image is of big size, you can compress it. Please visit this link, it will help you for sure.
https://dev.to/franciscomendes10866/image-compression-with-node-js-4d7h
You can try:
Remove
formData.append('petimage', data.petimage);
and use instead
data.petimage.forEach(pet => formData.append("petimage", pet))
The solution was trait the image as an object. The code is the next:
Object.values(data.petimage).forEach(pet => formData.append('petimage', pet))
Then it worked as expected.

Unable to send api response data from express to react after refreshing the page

I'm learning react and node js with express framework and I'm working on a project where I need to retrieve API data from express to react.
I retrieved data from backend express js where I made a simple json value. My backend server.js code is given below.
server.js
const express = require('express')
const app = express()
const PORT = 3001;
app .get('/api/contents',(req,res)=>{
const contents=[
{
"id":0,
"heading":"Joshua Tree Overnight Adventure",
"content":"A sight in the blue sea..."
},
{
"id":1,
"heading":"Catch waves with an adventure guide",
"content":"Lorem.."
},
{
"id":2,
"heading":"Catch waves with an adventure guide",
"content":"Lorem epsum ..."
}
];
res.json(contents)
})
app.listen(PORT,()=>{
console.log("express server is running...")
})
In react app, I used axios to retrieve those values from backend and tried to pass the api values of content with id= 0 as props in "TheLatestArticles" component. I have updated proxy in package.json in react to connect backend. The below code is the mainhomepage component where it is enclosed with TheLatestArticles component with props value
MainHomePage.js
import axios from 'axios';
import {useState,useEffect} from 'react'
function MainHomePage(){
const [content,setContent]=useState([]);
useEffect(()=>{
const fetchPosts = async ()=>{
const res =await axios.get("/api/contents")
setContent(res.data)
console.log(res)
}
fetchPosts()
},[])
return (
<>
<TheLatestArticle content={content} />
</>
);
}
export default MainHomePage;
TheLatestArticle.js
import cardImage from "./../../Images/card.jpg"
import './TheLatestArticleCard.css';
const TheLatestArticleCard=(props)=>{
console.log(props)
return(
<>
<div className="card">
<div className="image">
<img src={cardImage} alt="cardimg"/>
</div>
<div className="content">
<p className="heading">{props.content.heading}</p>
<p className="body-content">{props.content.content}</p>
<div className="details">
<p className="details-info">Travel <span className="details-info-2">/ August 21 2017</span></p>
</div>
</div>
</div>
</>
)
}
export default TheLatestArticleCard;
When I run the application, It displayed all the api values in the screen given below.
I console.log the api values inside useEffect and it displayed all the api values perfectly.
But when I refresh the page, the api value became undefined and gave me this error
Can you please solve me this issue with the reason behind this error? Thanks a lot!
Try it like this
{(content && content.length > 0) && <TheLatestArticle content={content} />}
Since your API call is async there won't be any data in content initially. After a while, your API is called and data is fetched. Then you will have data. To prevent TheLatestArticle to blow up we add some conditions when to show that component. The error in the screenshot is when you try to use a property heading from content where content is empty.
Now with the condition, TheLatestArticle will not render until there is some data.
Update
You are using <TheLatestArticle content={content} /> and content is assumed to be an object. But as per your code, it's an array. If you are not already using content.map((c)=> <TheLatestArticle content={c} />) you should do that.

How can I import an image from the express server to the client (in React)

I'm trying to show an image in react, which is neither a local image (in the client) nor an external image from the web but an image that is in the node.js express server (and I don't want to call it as if it was an external image, because the domain could change and it just doesn't seem right).
I know I can't just import it like I do with a local image in the client because we're speaking about different localhosts. I did try this:
loadImage = async (imageUrl) => {
const response = await fetch(`/api/images/${imageUrl}`);
const data = await response.json();
this.setState({ image: data });
}
componentDidMount() {
const { imageUrl } = this.props;
try {
this.loadImage(imageUrl);
} catch(error) {
console.log("Hay un error: " + error);
}
}
render() {
const { image } = this.state;
return(
<div>
<div>
<img alt="dontknowyet" className="blog-list-image" src={image} // and so on...
{image} does receive the correct path, but the image won't load and the console throws this error:
Not allowed to load local resource: file:///C:/Users/Dafna/Desktop/adrian/proyectos/esteticand/img/t4.jpg
So how can I make it work? and in case that I need to import the image file instead of just the link, how can I do that? (I can't update the state with an image...)
In order to access the path of the image it has to be done through the express server.
For example, if the (backend) server is running on port 4500 and the image is in a folder called images, and the express variable is called app, in the server file you have to use:
app.use(express.static('images'));
and then the image can be accessed in http://localhost:4500/nameoftheimage.jpg.
Do you have the api running on the same port as the React app?
You usually would make them run on different ports. Maybe it's got something to do with it.

Download image from Express (Back-end) using React (Front-end)

I have an image stored in Express server. I have been trying to download the image using the following method in a React component.
<a href={my_image_url_from_state} download>Download Image</a>
But when i click on the 'Download Image' image is not downloaded. I see this error message:
I am able to display the same image in img tag, ie
<img src={my_image_url_from_state} />
that means nothing wrong with URL.
Do I need to make any changes in Express to download any files?
You need to write a function and invoke it on OnClick of the download button.
<button onClick={() => {download()}}>Download</button>
download function would be:
function download() {
var link = document.createElement('a');
link.href = 'images.jpg';
link.download = '<The URL of the image>';
document.body.appendChild(link);
link.click();
}
working code in reactJS class
class App extends React.Component {
constructor() {
super();
}
render() {
return (
<div>
<img onClick={() => { download(); }} src="<The URL of the image>" />
</div>
);
}
}
function download() {
var link = document.createElement('a');
link.href = 'images.jpg';
link.download = '<The URL of the image>';
document.body.appendChild(link);
link.click();
}
I ended up here because I was looking for a way to download an image in my React app from cloudinary and I found the snippet above as a useful starting point. I was getting the same error as Darshn. I speculate that perhaps the reason it wasn't working is that the backend origin url was different than the client app's origin.
I then researched and found that the download attribute of an anchor element only works for same-origin URLs. See The Anchor element
I then found an article on Soumitra Roy Sarkar's Roy Tutorials that I was able to incorporate into a solution.
I determined that since I was pulling from a different origin I would need to fetch the image, convert it to a Blob, create a URL for it, attach the url to the anchor tag.
Since I already was using the Cloudinary React SDK I was able to add the cloudinary-core to my dependencies.
yarn add cloudinary-core
Then I imported it into my module
import cloudinary from 'cloudinary-core';
const cloudinaryCore = new cloudinary.Cloudinary({cloud_name: '<My Cloudinary Cloud Name>'});
My download function looks like:
function download({publicKey, name}) {
const downloadUrl = `${cloudinaryCore.url(publicKey)}.jpg`;
fetch(downloadUrl)
.then((img) => img.blob())
.then((blob) => {
let url = window.URL.createObjectURL(blob);
let link = document.createElement('a');
link.href = url;
link.download = name;
link.click();
})
}
The function can be called by an html element like this:
<button onClick={() => {download({publicKey: '12345', name: 'image.jpg'})}}>Download</button>

Resources