Unable to display image with dynamic path using Reactjs - javascript

I am working on Reactjs and i am using nextjs framework,Right now i am trying to fetch image data from database using axios,I am using loop for fetch image,Image in database is
like "http://xxxxxxxxxxxxxxxx/upload/blog/1669111567istockphoto-1354441996-170667a.jpg" means
i am getting full path of image,But whenever i am trying to fetch data then i am getting following
error
Error: Invalid src prop ...on `next/image`, hostname "diggdevelopment.com" is not configured under images in your `next.config.js`
Also i want if array(todoList) is not empty then loop should work(add condition if array not empty) and want to show number of records ( like 1 2 3 etc..)
I tried with following code
{post.map(todoList => (
<td><Image src={todoList.image} width={5}
height={50}/> </td>
))}

Open your next.config.js file and put your domain where images are stored like below:
const nextConfig = {
reactStrictMode: true,
presets: ["next/babel"],
images: {
domains: [
"diggdevelopment.com",
]
}
};
module.exports = nextConfig;
You can check if post is empty or not using below codes:
{post.length > 0 ? (
post.map((todoList, index) => (
<td key={index+1}>
<Image src={todoList.image} width={5} height={50} />
</td>
))
) : (
<p>No data</p>
)}
index will give you numeric value from 0 to the length of the array

Need to add the loader function
This will generate the URLs for your image. It appends a root domain to your provided src
<td><Image loader={() => todoList.image} src={todoList.image} width={5}

Related

How to display a message inside an empty div when a component doesn't render in it?

I have a div inside which I'm rendering dynamic card components(SearchRes):
<div className="search-res">
{games.filter(game => (game.background_image !== null)&&(game.ratings_count>38)).map(game=>
<SearchRes
key={game.name}
title={game.name}
rating={game.metacritic===null?<MdGamepad/>:game.metacritic}
genre={game.genres.map(genre=>genre.name+" ")}
imglnk={(game.background_image===null)?"":game.background_image}
gameid={game.id}
slug={game.slug}
plat={game.parent_platforms}
/>
)}
</div>
When the cards don't render (when they don't pass the filter conditions), I get a blank space. I want to display something like no results found when such thing happens, how can I implement this?
Currently I'm using CSS to implement it:
.search-res:empty::before {
content: "No data";}
but clearly this is not viable as the message is visible when the search is not even initiated:
If I understand your question, you want to conditionally render a "No Data" fallback only after you've fetched data and there is nothing to render.
Add a loading state and conditionally render a loading indicator.
Filter the games and in the render check that there is an array length (i.e. something to map), and conditionally render the array or the fallback text if there is a current search term.
Code
const [searchLoaded, setSearchLoaded] = React.useState(false);
// in search handler
// toggle searchLoaded false when initiating a search
// toggle searchLoaded true when search completes
const results = games.filter(
game => game.background_image !== null && game.ratings_count > 38
);
<div className="search-res">
{results.length
? results.map(game => (
<SearchRes
key={game.name}
title={game.name}
rating={game.metacritic === null ? <MdGamepad/> : game.metacritic}
genre={game.genres.map(({ name }) => name).join(" ")}
imglnk={game.background_image === null ? "" : game.background_image}
gameid={game.id}
slug={game.slug}
plat={game.parent_platforms}
/>
))
: searchLoaded && "No Data"
}
</div>
I would suggest to filter the array first, based on the conditions and then check if the array has length i.e. arr.length !== 0 and if that is the case, then map the results of the array to the card component. And if not then show the message that no data found. You would have to use if/else or ternary operator.
Thanks😊
if you are using a filter only for conditioning then there is no need for a filter instead you can use conditional rendering like this:
<div className="search-res">
{games.map(game=>
{(game.background_image !== null && game.ratings_count>38) ?
<SearchRes
key={game.name}
title={game.name}
rating={game.metacritic===null?<MdGamepad/>:game.metacritic}
genre={game.genres.map(genre=>genre.name+" ")}
imglnk={(game.background_image===null)?"":game.background_image}
gameid={game.id}
slug={game.slug}
plat={game.parent_platforms}
/> : "NO RESULTS FOUND"}
)}
</div>

How to use a HTML portion of a react.js file to another react.js file

I am trying to use the content of a separate react.js file to another react.js file. The js file contains a drop down & the drop down i want to show on the basis of a condition. Below is the js file which contains the drop down
const MyDataTableHeader = ({
first =0,
pageSize=0,
totalElements=0,
exportFile,
})
....
return(
<div className="someCss">
<Dropdown style={{width:100%, textAlign : "center"}}
value={selectedFileFormat}
options = {downloadOptions}
placeholder="Export As"
id={DOWNLOAD_OPTION}
name={DOWNLOAD_OPTION}
onChange={(e) => {
setSelectedFileFormat(e.value);
}}
/>
</div>
<div style={{padding:"1em"}} className = "someCss1">
<Button type="button" icon = "pi pi-download" iconPos="left" onClick={exportHandler}
/>
This portion of the code displays a Drop Down and a option to export, i want to use this code block within another js file , below is the content of the js file
const MySearchPanel = ({onSearch,onClear,exportFile }) =>
const searchHandler = () => {
if(//some Condition){
// i want to show the Drop down with export option here
You want to export your dropdown as a component and then inside your other file inside your condition you just render it using JSX.
import Dropdown from "../from/another/file" // const DropDown = require('from another file') if you do not wish to use module syntax.
const MySearchPanel = ({onSearch,onClear,exportFile }) =>
const searchHandler = () => {
// ...
return (
//if the codition is true show dropdown otherwise show nothing
<div>
{Condition ? <Dropdown /> : null }
</div>
);
// ...
I hope this answers your question.

Using an imported image based on json data character name

I am getting data from a json file and when I get the character name of the object i'd like the div to render an image from an image I had imported. But when I use src={char} and say for example the char from the json file is 'sage' i'd like to use the sage image. But doing this method does not work like that. Also I am successfully getting the data from the json file so no problems on that end.
Thanks!
import sage from '../../assets/images/agents/sage_thumb.webp';
import viper from '../../assets/images/agents/viper_thumb.webp';
import jett from '../../assets/images/agents/jett_thumb.webp';
import valorant_rank from '../../assets/images/ranks/valorant.png';
const renderBody = () => {
return matchData && matchData.map(({ id, char, name, roundsPlayed, performance, multiKills, team }) => {
return (
<tr key={id} className='tr-background'>
<td className='match-table__agent-cell'><img className='img-fluid' src={char} alt="" /></td>
</tr>
)
})
}
I would use an object to map the agent name to its image url
const imageByAgent = {
sage: "../../assets/images/agents/sage_thumb.webp",
viper: "../../assets/images/agents/viper_thumb.webp",
...
}
And for the image src you can fetch the url using the character name
<img className='img-fluid' src={imageByAgent[char]} alt="" />

Passing Data to Another Component OnClick

So, I'm having a bit of an issue when it comes to routing and managing my data.
The Listing component is essentially a ton of cards with movie data that I am fetching from a gist of mine. I created a component for each card using .map and adding the value to the prop.
My goal: When I click a button for any of the cards, I would like to go to a page and access that movie card's name dynamically.
For Example::
Suppose I click on a button that says "MoreInformation" for one particular movie card. I get routed to the MoreInformation page because the button will be contained in a Link.
Inside the MoreInformation Page/Component I would like to dynamically add:
<h1>{name}</h1>
This is just a basic example of what I am trying to accomplish, but in other words how do I transfer the data of that particular movie card to the MoreInformation page so that I can access it to add dynamic data.
I will be extremely grateful if I can get feedback as this project is time sensitive... Thanks guys.
const MoviesPage = () => {
const [movies, setMovies] = useState([])
useEffect(() => {
axios
.get(
`https://gist.githubusercontent.com/ernestosotelo/9932c659b460e5ddeec8a8ae76164a0d/raw/ce8d7b248f61e73bf3c767538728505d6bac9835/json`
)
.then(res => {
const data = res.data
setMovies(data)
})
}, [])
return (
<Layout>
<div style={{ background: "hsl(215, 100%, 3%" }}>
<TopThree />
<p style={{ color: "#e0dfe2", fontSize: "1.7rem", marginTop: "3rem" }}>
<b
style={{
padding: ".5rem 1.5rem .5rem 1.5rem",
background: "#f9ba00",
fontSize: "2rem",
marginLeft: "4rem",
color: "black"
}}
>
!
</b>{" "}
Click 'Remove' to remove movies you definitely will not watch! There
is an undo option.
</p>
<div className={listingCSS.block}>
{movies.map(movie => {
return (
<Listing
key={movie.name}
name={movie.name}
plot={movie.plot}
date={movie.releaseDate}
genre={movie.genre}
imdbRating={movie.imdbRating ? movie.imdbRating : "N/A"}
tomatoRating={movie.tomatoRating ? movie.tomatoRating : "N/A"}
metaRating={movie.metaRating ? movie.metaRating : "N/A"}
erbertRating={movie.erbertRating ? movie.erbertRating : "N/A"}
tmdbRating={movie.tmdbRating ? movie.tmdbRating : "N/A"}
movshoRating={movie.movshoRating}
streamOn={movie.streamOn}
poster={movie.poster}
alt={movie.name}
/>
)
})}
</div>
</div>
</Layout>
)
}
You need to create a route for displaying the data passed. For example
<Route path="/movieInfo/:name" exact component={MoreInformation} />
In your listing create a link to more information component
<Link to={`/movieInfo/${this.props.name}`}>More info</Link>
In your MoreInformation component access the prop like
const { name } = this.props;
Simple Demo here
If you are using functional components, you can retrieve the value, like below. Inside match params.
function MoreInformation(props) {
const name = props.match.params.name;
return <h1>{name}</h1>;
}
You could use JS with HTML 5 elements to store the data on session (sessionStorage.getItem() and sessionStorage.setItem()) or locally (localStorage.getItem() and localStorage.setItem()).
If you prefer storing the data on setItem by variables :
var session_data = sessionStorage.myValue //For session only
var local_data = localStorage.myValue //For local
sessionStorage.myValue = 'value' //For session only
localStorage.myValue = 'value' //For local
Remember also : To store JavaScript objects you should set and change them to a string value :
sessionStorage.myObject = JSON.stringify(myObject); // Setting the object to a string
And parsing it back to object to retrieve the data when using getItem :
var myObject = JSON.parse(sessionStorage.myObject); // Parsing JSON back from string to object
ALSO : You could use window.name to store information, but note that it works only when the same window/tab is used, so make sure your button or link has the target value set to _self.
You can read about storing data without cookies with JavaScript HERE
For info about the Web Storage API : https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
For info about PersistJS (might interest you) : https://github.com/jeremydurham/persist-js

How to make dynamic Image with states - react native

my function is:
getImage(page){
return
(
<Image
style={{position:'absolute',height:'60%',width:'90%',padding:50,bottom:30 ,alignSelf: 'center' }}
source={require('../../images/backgrounds/introduction/'+page.img)}
/>
)
}
render(){
return (
...
{this.getImage(activePage)}
)
}
but I got this error message:
Error: /Users/***/components/login/Introduction.js:85:14: calls to `require` expect exactly 1 string literal argument, but this was found: `require('../../images/backgrounds/introduction/' + page.img)`.
Instead of concatenation in require() you can use state.
Initialize one state say imageArray={page1:require('link of page 1 image'),page2:require('link of page 2 image')}
Then in getImage() use Image like this,
<Image
style={{position:'absolute',height:'60%',width:'90%',padding:50,bottom:30 ,alignSelf: 'center' }}
source={this.state.imageArray[page]}
/>
where page is the key from one of item of imageArray state.

Categories