Display images with a loop in a React component - javascript

I am using Gatbyjs, and I would like to display multiple images in a card component. It seems that this solution shoud work, but it does not. I don't get any other specific error than:
GEThttp://localhost:8000/[object Module]
[HTTP/1.1 404 Not Found 13ms]
I tried to use an absolute path for the src attribute and it didn't work either. Neither did something nasty like importing every images in the file of the card component, and calling them this way:
<img src={`${Img}`} />.
Here is the component:
const ServiceCard = ({ title, subtitle, text, logos }) => {
const displayLogos = logos.split(",").map((logo) => (
<li key={logo} className="tech-logo">
<img
key={logo}
src={require(`../../images/tech-logos/${logo}.png`)}
alt={`${logo} logo`}
height="30px"
width="30px"
/>
</li>
));
return (
<div className="service-card">
<h1 className="service-card-title">{title}</h1>
<h2 className="service-card-subtitle">{subtitle}</h2>
<p className="service-card-text">{text}</p>
<ul className="tech-logo-list">{displayLogos}</ul>
</div>
);
};
Edit:
This is the way this component is used :
<ServiceCard
title="Text string"
subtitle="e-shop"
text="random text"
logos="React,Ror,Gatsby,Wordpress,Drupal,Js,Php,Mysql,Pgsql"
/>
So as we can expect, console.log("tech is " + logo); in displayLogos returns a new string for every string concatenated between comma.

Well, I managed to solve this by adding .default at the end of the require():
const displayLogos = logos.map((logo) => (
<li key={logo} className="tech-logo">
<img
key={logo}
src={require(`../../images/tech-logos/${logo}.png`).default}
alt={`${logo} logo`}
height="30px"
width="30px"
/>
</li>
));
Found the idea here.

Related

Outputs the same value even though tag names has different values in the DOM

I'm iterating on every element(post) on an array and each HTML tag name has a value of post._id. In the DOM, the outputs has different values as excepted but when I try to capture those values on the react Profile component, the console.log(el) outputs the same value for every different click of the elements in the DOM.
I have a links on every post on the profile, and when onClick event occurs on every link, I'm trying for each of them to have the id I gave to the tag name (post._id)
function handleReplyTweet(e) {
e.preventDefault();
appDispatch({
type: 'openReply',
});
let el = document.getElementById('reply').name;
console.log(el);
setTweetId(el);
console.log(tweetId);
}
HTML
tweetsData
.map((post, index) => {
return (
<div key={index} className="main-view__user-feed">
<img src={post.avatar} alt="image tweet"></img>
<div className="main-view__user-feed__author">
<div className="name">
<h2>
{post.name} {post.surname}
</h2>
<a href="#" className="username__author">
#{post.username}
</a>
<span> 9 June</span>
</div>
<Link
to={`/status/${post._id}`}
className="author_post-viewpost"
>
{post.text}
</Link>
<div className="icons">
<section>
<li className="top-nav__item top-nav__item--active">
// Tyring to capture the names here from the DOM.
<Link
id="reply"
to={''}
onClick={handleReplyTweet}
className="top-nav__link"
name={post._id}
>
<svg className="top-nav__icon">
<use xlinkHref="img/sprite.svg#icon-bubble2"></use>
</svg>
<span>{post.comments.length}</span>
</Link>
</li>
</section>
For getting the element in react (like input value etc) it is better to use useRef hook. But in your case you don't need to use it.
You can simply pass a function in onClick and call handleReplyTweet function from there with post id.
Hope below code sample I created for you helps:
https://playcode.io/926104/

Giving random background images to each div in the for loop in Vue Js

I have a v-for loop that runs on a div and gives out a bunch of tags. I need each of those tags to have a different src. Everything that I have tried so far results in all the tags getting the same source. Is there any way I can do this?
<div class="wrapper" v-for="result in results" :key="result.index">
<div class='small-card'>
<img class="thumbnail" :src="backgroundImage">
<div class="text-elements">
<span class="md-display-2 minicard-title">{{result.name}}</span>
<br class="break">
<span class="md-display-1 minicard-subtitle">{{result.state}}</span>
</div>
</div>
<br class="br3">
</div>
I recently did this in a project.
What I ended up doing was setting the style tag for background-image using the :style attribute.
Depending on how you are acquiring the image source, you will need to either create a method to return a random image URL, or access the image URL provided in the object. As you said "random" I assume the first approach would be the best fit.
Here's a very rough and untested example:
<template>
<div>
<div
v-for="index in 10"
:key="index"
:style="{'background-image': randomImage()}"
/>
</div>
</template>
<script>
export default {
name: 'Example',
data() {
return {
images: ['1.jpg', '2.jpg', '3.jpg', '4.jpg'],
};
},
methods: {
randomImage() {
return `url("${
this.images[Math.floor(Math.random() * this.images.length)]
}")`;
},
},
};
</script>
Make sure that the :style="{'background-image': randomImage()}" contains a () to ensure the method is called vs being referenced.

Using generic array name in template

I am really new to vue.js and HTML. I have two components that are working together. A photo-gallery and a tag-component. The tag-component uses the tags array to get the tags for a image. What i would like is to have a tag array for each image. I figured i could use the imageIndex and append that to the array name so I was string something like :tags=tags+imageIndex.
But if I do that, it does not work (i think it is not recognized as an array any more...) . My question is, is there a way to enter that in to the template, so that i have for each image an array with the name tags{index}?
Many thanks for the help!
Robin
<div id="SingleFile">
<button
id="refreshbtn"
class="btn btn-primary btn-margin"
#click="updateFileList">
refresh
</button>
<gallery :images="images" :index="index" #close="index = null"></gallery>
<div
:key="imageIndex"
:style="{ backgroundImage: 'url(' + image + ')', width: '300px', height: '200px' }"
#click="index = imageIndex"
class="image"
v-for="(image, imageIndex) in images"
>
<div>
<vue-tags-input
v-model="tag"
:tags="tags"
#tags-changed="newTags => tags = newTags"
/>
</div>
</div>
<div class="upload">
<upload-image url="http://localhost:8080/user" name="files" max_files="100"></upload-image>
</div>
</div>
You could use a method to achieve that:
<vue-tags-input
v-model="tag"
:tags="getTags(imageIndex)" ... >
and define it like :
methods:{
getTags(i){
return this['tags'+i];
}
}
by assuming that you have in your data object something like :
data(){
return{
tags0:[],
tags1:[],
...
}
}
or any property which has that syntax tags+index

react js rendering images using props in url

I want to render images from my server ftp using props in React JS.
I have like:
render(){
console.log(this.props.product.image) //Which gives me the product image name properly
return(
<div className={this.props.openModal ? "modal-wrapper active" : "modal-wrapper"}>
<div className="modal" ref="modal">
<button type="button" className="close" onClick={this.handleClose.bind(this)}>×</button>
<div className="quick-view">
<div className="quick-view-image"><img src={`${this.props.product.image}`} alt={this.props.product.name +' image'}/></div>
<div className="quick-view-details">
<span className="product-name">{this.props.product.name}</span>
<span className="product-price">{this.props.product.price}</span>
</div>
</div>
</div>
</div>
)
}
In the log i am getting the image name, but why not the same in the img src attribute.
I tried to give the same line in src like i have given in console.
But just gave a try like:
Log data:
Ok i updated the full path, now image is rendering.
<img src={'http://localhost:5000/images/products/'+this.props.image}

change img that in class in class in id

I read about it but still I'm not able to make it work.
I have an image (empty heart) that I would like to change to a different image (full heart) in order to indicate it was added to the wish list.
here is my code:
<tbody class="mainImgs">
<div ng-repeat="party in showtop5" ng-class=party.name>
<img ng-src="{{party.image}}">
<h2 id="title">{{party.title}}</h2>
<h3 id="description">{{party.description}}</h2>
<button href="#" class="imageClick" ng-click="click(party.title, party.description, party.image)">
<img ng-src="../images/emptyHeart.png" id="heart" click="myFunction(party.name, imageClick)">
</button>
<img ng-src="{{party.img}}" id="pace">
</div>
</tbody>
and my script:
function myFunction(myclass1, myclass2){
document.getElementByClass(myclass1).getElementByClass(myclass2).getElementById("heart").src = "../images/fullHeart.png";
}
what did I do wrong?
without sending the class - and trying to find image only by id - t works only for the first object heart that is printed
I think if its just about changing image then it can be handled pretty straight forward:
In html
<button href="#" class="imageClick" ng-click="click(party.title, party.description, party.image)">
<img ng-src="{{imgPath}}" id="heart" ng-click="myFunction(party.name, imageClick)">
</button>
In Controller:
$scope.imgPath = "../images/emptyHeart.png";
$scope.myFunction= function (name,imageClick){
// use promise to monitor the server response of adding product to Wishlist
("YOUR_PROMISE_CALL").then(
function(success){
$scope.imgPath = "../images/fullHeart.png"; // Bingo !!
},
function(error){
// take appropriate action
},
)
}

Categories

Resources