upload image dynamically in react js - javascript

I want to make a product presentation page where I retrieved the addresses of the images, then I have but the address that I retrieved it but the image does not upload (the link is correct).I found some source which said that you have to use require ('../ image / name_image.jpg') when I have but the code like it works but when I used list.image (variable) it does not work
the result that i got it
the code that creates the image
get data results
file structure

Add your image folder inside the public folder: public/image/
then use <img src="/image/m1.jpg" />

You can try this and you need to declare state images with empty array, and declare the function loadImages that will load your images dynamically:
loadImages() {
lists.forEach((item, i) =>
import(item.image)
.then(image => {
this.setState(state => ({ images: [...state.images, image] }))
})
)
}
In your jsx edit this line:
src={this.state.images[index]}

or you can use:
<img src={require(../image/m1.jpg)}/>

Related

How to map all images from a folder to a javascript array?

I'm making a react front end to a database, I'd like to be able to upload images to a folder (which I can) and then put all of those images into a mui image list (docs here: https://mui.com/material-ui/react-image-list/).
To do this, I need to give a src for each image, but I don't necessarily know how many images or what the names of said images will be in the final website once it's live.
How can I make a loop that will both tell how many files are in a folder as well as extract the names of those files to form them into an array?
I've seen code like this:
function importAll(r) {
let images = {};
r.keys().map((item, index) => { images[item.replace('./', '')] = r(item); });
return images;
}
const images = importAll(require.context('./images', false, /\.(png|jpe?g|svg)))
But it isn't quite what I want, because this still requires knowing the file's name before you can actually use it rather than being able to just call it by an array that points to that name

[api](Unsplash Api) trying to generate random pictures for my testing database

I'm using a nodejs package called casual Which basically lets one generate random data
Im defining this method for generating imgs
casual.define('portrait', () => ({
uri: `https://source.unsplash.com/collection/9948714?sig=${casual.integer(1, 100)}`
}));
From this, I create an array of images like this :
[
{"uri":"https://source.unsplash.com/collection/9948714?sig=37"},
{"uri":"https://source.unsplash.com/collection/9948714?sig=32"},
{"uri":"https://source.unsplash.com/collection/9948714?sig=91"},
]
I'm supposed to get a different image each time, but the PROBLEM is that I get the same picture 3 times, even with the sig.
What I'm I doing wrong?
[SOLVED]
casual.define('portrait', () => ({
uri: `https://source.unsplash.com/collection/9948714?${casual.integer(1, 100)}`
}));
generating
[
{"uri":"https://source.unsplash.com/collection/9948714?37"},
{"uri":"https://source.unsplash.com/collection/9948714?32"},
{"uri":"https://source.unsplash.com/collection/9948714?91"},
]
just adding a number instead of sig=number worked

How to have JavaScript functions work across different HTML pages?

I am building a website with several HTML pages, and going to fill up info on different pages through an API. I have added onclick listeners to HTML elements like this:
// ASSIGNING ELEMENTS AS VARIABLES
const EPL = document.getElementById('epl');
const bundesliga = document.getElementById('bundesliga');
const laliga = document.getElementById('laliga');
// ONCLICKS
EPL.onclick = function() {
getStandings('2021');
location.replace('standings.html');
}
bundesliga.onclick = function() {
getStandings('2088');
location.replace('standings.html');
}
laliga.onclick = function() {
getStandings('2224');
location.replace('standings.html');
}
When one of these is clicked, I call a function (getStandings) with its unique argument to fetch some data from the API. I also want to move to another HTML page, for which I used location.replace.
I'm caught in a dilemma: if I use the same JS file for every HTML page, when I get to the new HTML page, I get errors as the new HTML page does not have every element:
main.js:41 Uncaught TypeError: Cannot set property 'onclick' of null
But if I use different JS files, maybe one JS file for each HTML file, I cannot carry forward the bits of information I need. How can I get to the new HTML page, with its own JS file, without stopping and losing everything in the function I'm in currently, under the JS file of the old page? For example, the argument '2021' or '2088' are to be passed into the getStandings() function which will populate the new HTML page with data from an API. If I jump to a new HTML page with a new JS file, this is lost.
Is there a better way to organise my files? 😐😐😐😐😐
You can set your event listeners on the condition that the elements are not null e.g.
const EPL = document.getElementById('epl');
const bundesliga = document.getElementById('bundesliga');
const laliga = document.getElementById('laliga');
if(EPL){
EPL.onclick = function() {
getStandings('2021');
location.replace('standings.html');
}
}
etc...
Solved! As amn said, I can add URL parameters to the end of the URL of the new HTML page, then get the variables from its own URL once I'm on the new HTML page.
I think I would rather use classes instead of IDs to define the listener, and maybe IDs for dedicated action.

Injecting gatsby-image into html created from markdown using ReactDOMServer.renderToString

Minimum Reproducible Example on Github
I'm trying to inject some images into my pages created from markdown. I'm trying to do this using ReactDomServer.renderToString()
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<Img fluid={data.allFile.edges[0].node.childImageSharp.fluid} />)
}
})
...
}
The img is showing as a black box, if I right click the image I can open it in a new tab, which shows the image as it is supposed to be.
How I understand the problem
The image html is correctly inserted into the page
gatsby-image loads the lowest quality image and applies some inline
styles. All that information is present in the html) This is done to
enable the blur-up effect on the image for a better UX.
The client side code that would load a higher resolution image and remove the inline styles is never applied.
Useful diagnostic information
The function inside useEffect does not get run on the server-side, but rather on the client after the component has mounted. It's possible to verify this by adding a console.log statement inside the effect and seeing that it is logged on the browser's console.
Source of the problem
ReactDOMServer.renderToString() only builds the HTML that's required by a component, it then requires the component to be hydrated.
Direct fix
You can use ReactDOM.render to put the image on the page, given that the effect will execute client side. I have a PR showing that here.
Recommended approach
You could instead import the image inside the mdx component and directly render it there. Your gatsby config can already support this 👍 In content/blog/hello-world/index.mdx, you can replace the injectImage div with this ![A salty egg, yummm](./salty_egg.jpg) (where the text inside the [] is the alt text)
This documentation might be helpful
https://www.gatsbyjs.org/docs/working-with-images-in-markdown/
https://www.gatsbyjs.org/packages/gatsby-remark-images/
Hope that helps! 😄
I have faced this problem before with my first Gatsby project.
The problem similar to this chat and the error image issue here.
If you replace GatsbyImageSharpFixed_withWebp_tracedSVG like they talked in spectrum chat above, or this is my current code for example, basically is related to WebP new image format.
export const query = graphql`
query {
allImageSharp {
edges {
node {
fluid(maxWidth: 110) {
aspectRatio
originalName
sizes
src
srcSet
srcWebp
tracedSVG
}
}
}
}
}
`;
Hope this help.
I think the problem could be in the useEffect
const componentCreatedFromMarkdown = ({data}) => {
...
useEffect(() => {
const injectDivs = Array.from(document.getElementsByClassName('injectDivs'))
injectDivs.forEach((aDiv) => {
aDiv.innerHTML = ReactDOMServer.renderToString(<MyComponent args={myArgs} />)
}
},[])
...
}
I think you should try to add useEffect(()=>{},[]), the second argument to refresh the image only when the component is mounted, without this the image will be refreshed each time.

It's possible to call html and css tags inside a text file?

First question here! So, i'm at the beginning of my studies and i have searched on Google and didn't found anything about this scenario:
I'm developing a website that contains a lot of files (over 500 on the same page, it's a list of cards). If i write all the tags of those images the code will be a mess.
I would like to know if would be possible for example to create a ".txt" file with all the img tags inside it, and make a call through JavaScript or jQuery, so that they are displayed on the screen. For example:
<div class="tab-pane fade in active" role="tabpanel" id="all-cards">
<img src="../img/cards/en-gb/xln-cards/black/fatom-fleet-captain.png">
<img src="../img/cards/en-gb/xln-cards/blue/kopala-warden-of-waves.png">
<img src="../img/cards/en-gb/xln-cards/green/colossal-dreadmaw.png">
<img src="../img/cards/en-gb/xln-cards/red/bonded-horncrest.png">
<img src="../img/cards/en-gb/xln-cards/white/adanto-vanguard.png">
<img src="../img/cards/en-gb/xln-cards/multicolored/admiral-beckett-brass.png">
<img src="../img/cards/en-gb/xln-cards/artifacts/pirate's-cutlass.png">
<img src="../img/cards/en-gb/xln-cards/lands/unknow-shores.png">
</div>
Put all those on a .txt and call on that page "cards-database.html".
Thank you!
Sure, store them in a JSON file on your server:
[
"black/fatom-fleet-captain",
"blue/kopala-warden-of-waves",
"green/colossal-dreadmaw"
]
Then make a request for that file using fetch() (in my opinion, slightly shorter than $.ajax), iterate over the list and build the image tags with $.append():
fetch('list-of-images.json')
.then(response => response.json())
.then(images => {
for (let card of images) {
$('#all-cards').append(`<img src="../img/cards/en-gb/xln-cards/${card}.png">`)
}
}
})
But as Daniel noted, there is no particular advantage to doing this. In fact, you'll take a performance hit because you have to load the page, then load the list of images, then start getting the images.
A better idea is just to store the array directly in the script file that does the appending loop, like:
const images = [
"black/fatom-fleet-captain",
"blue/kopala-warden-of-waves",
"green/colossal-dreadmaw"
];
for (let card of images) {
$('#all-cards').append(`<img src="../img/cards/en-gb/xln-cards/${card}.png">`)
}
Additional:
Don't store your entries twice. I was going to propose this in the original answer but got lazy.
Just store your cards as an object whose keys are the colour, and the card names as an array within each colour:
const cards = {
"black": [
"fatom-fleet-captain"
],
"blue": [
"kopala-warden-of-waves"
],
"green": [
"colossal-dreadmaw"
]
};
Then you can get the cards of just one colour:
// Get all the black cards
for (const card of cards.black) console.log(`black/${card}.png`)
Or you can flatten the object to get all cards in one array, here I've use for...of and for...in and an extra array for clarity:
const all_cards = [];
for (let colour in cards) {
for (let card of cards[colour]) all_cards.push(`/${colour}/${card}.png`)
}
Adjust as needed.
You may be looking at that cosnt in const all_cards = [] and wondering how that could work. Note that const prevents reassignment (meaning with =) not operations like pushing to an array, or mutating object properties.

Categories