How to map all image url from array - javascript

Hi all I have following code: my code
I am receiving some response from backend.
I am trying to get all images from imagesData and show in ImageComponent component.
I am using map function in my main component in this way:
{!!res &&
res.map((data) =>
{
return <ImageComponent key={data.publicId} {...data} />;
})}
and here is my ImageComponent component:
const ImageComponent = ({ img }) => {
return (
<div>
<img src={img} alt="pic" />
</div>
);
};
But something went wrong please help me to resolve this problem.

You're applying the map method on res, which is an object not an array. Map method is made for Arrays. All you have to do is access the image array present in you Object and then, apply the map.
Read about map here
return (
<div className="App">
{!!res &&
res.imagesData.map((data) => {
return <ImageComponent key={data.publicId} {...data} />;
})}
</div>
);
In your ImageComponent, you have to pass url in your destructured props as it is the url property that contains the actual url of your image
const ImageComponent = ({ url }) => {
return (
<div>
<img src={url} alt="pic" />
</div>
);
};

res is not an array.
From what I see I suppose you wanted to do this
{!!res &&
res.imagesData.map((data) =>
{
return <ImageComponent key={data.publicId} {...data} />;
})}

Related

react component return problem when props are null

export default function RenderPages({storage, setStorage, state, setState}){
let elRefs= useRef()
if(!storage) return
if(!state.currentFileId || !state.currentFolderId) return
const content = storage[state.currentFolderId][state.currentFileId].content
return (
<div className="writing">
<input ref={elRefs}/>
{content.map((page, index)=>
<div className='textarea'>
<textarea placeholder='write here' value={page} id={"page"+index} onChange={(e)=>onChange(e, index)} rows={rows} cols={cols}></textarea>
</div>)}
</div>
)
}
There are some props(state, storage) and they are sometimes null value. What I am doing now is checking the values of state and storage, returning blank early if those values are null. If I don't return in advance, the variable "content" get error because it needs state and storage value. Now this is the problem. I want to use "useRef", and if the component return early "elRefs" is assigned null value, so I can't get DOM element. What should I do?
I put your booleans into single function and seperated the renderable part of component. If bool is false, that component is simply not rendered. Of course you can put in there other component which shows error data or loading gif or something like that. Hope this works!
export default function RenderPages({ storage, setStorage, state, setState }) {
const elRefs = useRef()
const content = storage[state.currentFolderId][state.currentFileId].content
// content to render in seperate component
const Pages = () => (
<div className="writing">
<input ref={elRefs} />
{
content.map((page, index) =>
<div className='textarea'>
<textarea
placeholder='write here'
value={page} id={"page" + index}
onChange={(e) => onChange(e, index)}
rows={rows}
cols={cols}
/>
</div>
)
}
</div>
)
// decide to or not to render component
const renderable = storage &&
state.currentFileId &&
state.currentFolderId
return (
<>
{
renderable
? <Pages />
: <></> // returns empty component
}
</>
)
}

How to make image clickable and redirect to its introduction value page in Reactjs

I have called an api then pick let says drinks. i picked drink name and images. Now i need to find the details about that drink.On clicking in this image it show about that . which all these think are present in the api. But i dont know how to do it.
import React from "react";
const DrinkList = (props) => {
// const handleTextShow
return (
<>
{props.drinks.map((drink, index) => (
<div>
<img
src={drink.strDrinkThumb}
alt="drink"
width="300"
height="300"
onClick={handleTextShow}
></img>
</div>
))}
</>
);
};
export default DrinkList;
strDrinkThumb shows photo about that and details be strDetails.
Just pass strDetails to your handleTextShow function
const DrinkList = (props) => {
const handleTextShow = (drinkDetail) => {
console.log(drinkDetail)
}
return (
<>
{props.drinks.map((drink, index) => (
<div>
<img
src={drink.strDrinkThumb}
alt="drink"
width="300"
height="300"
onClick={() => handleTextShow(drink.strDetails)}
></img>
</div>
))}
</>
);
};
export default DrinkList;

How do I add destructuring here in the case

I learn React and JavaScript. I stumbled on this Eslint suggest I do destructuring like the image warning suggest but where do I add that. I try like const { errorComponent }= props; but that did not work inside a const
The code:
import '../../styles/error.scss';
const Error = props => (
<div className="error-message">
{props.errorComponent ? <props.errorComponent {...props} /> : <p className="alert">Unable to preview file</p>}
</div>
);
export default Error;
Additionaly to my comment, your components might look something like this:
const Error = ({ errorComponent: Component, ...props }) => (
<div className="error-message">
{Component ? (
<Component {...props} />
) : (
<p className="alert">Unable to preview file</p>
)}
</div>
);
A better option is to use children prop instead.
const Error = ({ children }) => (
<div className="error-message">
{children || <p className="alert">Unable to preview file</p>}
</div>
);
As far as I understand you can destructure it look like this
const Error = props => {
const {errorComponent, otherProperty} = props
return (<div className="error-message">
{errorComponent ? <errorComponent {otherProperty} /> : <p className="alert">Unable to preview file</p>}
</div>)
}
export default Error;
Try this approach.
const Error = ({ errorComponent, ...props }) => {
const ErrorComponent = errorComponent;
return (<div className="error-message">
{errorComponent ? <ErrorComponent {...props} /> : <p className="alert">Unable to preview file</p>}
</div>)
}
<errorComponent> - it won't work as expected because all the custom components should start with block letter(if not, react will consider it as in-build Html tag)

TypeError: Cannot read property 'map' of undefined - how to access an array in a local json API

I was able to import an api JSON locally using fetch, the api is available in this url if you want to view it.
 
The problem is the following, when passing the state searchString I get the following error:
'TypeError: Can not read property' map 'of undefined'
I believe that is because I am importing the complete json object, whereas I need to access only key results.
File App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
searchString: []
};
}
componentDidMount() {
fetch('./recipes.json')
.then(response => response.json())
.then(json => console.log(json ))
.then(json => this.setState({ searchString: json }));
}
render() {
return (
<div className="App">
<Navbar />
<div className="container mt-10">
<div className="row">
<RecipeItem list={this.state.searchString}/>
</div>
</div>
</div>
);
}
}
File RecipeItem.js
const RecipeList = ({ searchString }) => {
<div>
<img className="card-img-top img-fluid" src={searchString.href} alt={searchString.title} />
<div className="card-body">
<h5 className="card-title">{searchString.title}</h5>
<p className="card-text">
<strong>Ingredients: </strong>{searchString.ingredients}
</p>
</div>
</div>
}
const RecipeItem = (props) => {
return (
<div className="col-sm-3 mt-4">
<div className="card">
{props.list.map((searchString, index) =>
<RecipeList searchString = {searchString} key={index} />
)}
</div>
</div>
)
}
RecipeItem component doesn't have the data when it's initially mounted, since you're doing a fetch call. So that's why you receive the error.
You can add a simple check if you have data and then do the map/filter/ or anything else:
{props.list && props.list.map((searchString, index) =>
<RecipeList searchString = {searchString} key={index} />
)}
In addition to #chiril's answer, you need to check that the searchString list is actually an array when you set the state (so that the map function will be available):
.then(json => this.setState({ searchString: json })); // check json object is an array

TypeError: Cannot read property 'map' of null

I couldn't understand why...here is the GitHub repository: https://github.com/Dronrom/React-test
That’s because you initialized peopleList as null in your component. So map works only on arrays so you need to check peopleList whether its really an array before doing map on it so
Change
renderItems(arr) {
return arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
}
To
renderItems(arr) {
if(arr){
return arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
}
}
I think your issue may be that react renders once before componentDidMount(). This is an issue because your calling map on arr which is null. const { peopleList } = this.state; you set people list to your current state which you set as default to be null, state = {peopleList: null}; then you later call this.renderItems(peopleList); which people list is still null at this moment so you are getting the Cannot read property 'map' of null error.
I belive something like componentWillMount is what you need instead. I recommend looking at this post which has a similar issue of react life cycle methods. React render() is being called before componentDidMount()
the answer is very simple: the type of the input isn't array type, it might be null or undefined. so that it doesn't have .map function.
How to fix:
Make sure your input must be array type before call renderItems().
render(){
const { peopleList } = this.state;
const items = (peopleList && peopleList.length) ? this.renderItems(peopleList) : null;
return(
<ul className="item-list list-group">
{items}
</ul>
);
}
Or:
Make sure your input must be array type before do mapping:
renderItems(arr) {
return !arr ? null : arr.map(({id, name}) => {
return (
<li className="list-group-item"
key={id}
onClick={() => this.props.onItemSelected(id)}>
{name}
</li>
);
});
{product.size?.map(c=>(
<FilterSizeOption key={c}>{c}</FilterSizeOption>
))}
Wrapping the return statement with a if statement worked for me
So changed
return (
<div>
<Navbar />
{countries.map((country, i) => {
return (
<div>
<span key={`${country.name.common}${i}`}>
{country.name.common}
</span>
</div>
);
})}
</div>
);
to this
if (countries) {
return (
<div>
<Navbar />
{countries.map((country, i) => {
return (
<div>
<span key={`${country.name.common}${i}`}>
{country.name.common}
</span>
</div>
);
})}
</div>
);
}

Categories