map function not rendering in react jsx - javascript

I am new to react and was trying to use a map function inside jsx to render an array. However nothing gets rendered inside the loop .
I am passing data to my child component like this:
{showMaterialConfirmModal && (
<MaterialModalConfirm
closeModal={setshowMaterialConfirmModal}
orderList={orderListE}
itemList={itemListE}
errorList={errorListE}
title="Success"
/>
)}
and inside the child component I am calling the map function like this:
<Card>
<GridContainer>
<GridItem xs={12}>Design Successful for: 0</GridItem>
<h5>Order:{props.orderList[0]}</h5>
{props.orderList.map((order, i) => {
<div>
{order}
<h1>Hi</h1>
{/* <GridItem xs={12}>
order/item no {order[i]}/{props.itemList[i]} due to{" "}
{props.errorList[i]}
</GridItem> */}
</div>;
})}
</GridContainer>
</Card>
The data in orderList is coming in the tag however nothing gets printed which is inside the loop.
I have checked various documents to run the map function however I am at a loss as to why nothing is getting printed .
Please help

I think you are missing a return here:
{props.orderList.map((order, i) => {
return (
<div>
{order}
<h1>Hi</h1>
</div>);
})}
or
{props.orderList.map((order, i) => (
<div>
{order}
<h1>Hi</h1>
</div>
))
}

Related

Clicking on an element on google map doesnt scroll to the relevant item on list in react

When I am printing the childElement on the console when clicking on the cards it gets displayed correctly
But when I am trying to use CreateRef to scroll to the card on list when the user clicks on that specific card on Google Maps
Yt Tutorial that I am following skipped to the revelant timestamp : https://www.youtube.com/watch?v=UKdQjQX1Pko&t=5274s
Github Link of the code: https://github.com/adrianhajdin/project_travel_advisor
I am using useEffect like this
(in List.jsx)
const [elRefs, setElRefs] = useState([]);
useEffect(()=> {
const refs = Array(places?.length).fill().map((_,i)=> elRefs[i] || createRef());
setElRefs(refs);
},[places]);
Grid Element
<Grid item key={i} xs={12}>
<PlaceDetails
place={place}
selected={Number(childClicked) === i}
refProp={elRefs[i]}
/>
</Grid>
in (PlaceDetails.jsx)
if(selected) refProp?.current?.scrollIntoView({behavior:"smooth", block:"start"})
App.js Code
const [isLoading, setIsLoading] =useState(false);
useEffect(()=>{
setIsLoading(true);
getPlacesData(bounds.sw,bounds.ne)
.then((data)=>{
console.log(data);
setPlaces(data);
setIsLoading(false);
})
},[coordinates,bounds]);
<Grid item xs ={12} md={4}>
<List places ={places}
childClicked={childClicked}
isLoading={isLoading}
/>
Now adding a logical block in List.jsx
{isLoading ? (
<div className={classes.loading}>
<CircularProgress size ="5rem" />
</div>
) :(FormControl Code)}
Here are two warnings i am getting
React Hook useEffect has a missing dependency: 'elRefs'. Either include it or remove the dependency array
Received false for a non-boolean attribute `$hover
I solved the error by setting
const [childClicked ,setChildClicked] =useState();
instead of
const [childClicked ,setChildClicked] =useState(null)
and enclosing the App.js code like
{isLoading ? (
<div className={classes.loading}>
<CircularProgress size ="5rem" />
</div>
) :(<Fragment>FormControl Code</Fragment>)}
instead of
{isLoading ? (
<div className={classes.loading}>
<CircularProgress size ="5rem" />
</div>
) :(FormControl Code)}

Create custom TabPane using react-bootstrap

I would create custom Tab Form from JSON, using React and boostrap. Using this function my code work correctly.
function DisplayForm(props) {
return(
<div className="row">
<Tabs className="mb-3">
{Array.from(new Map(Object.entries(json))).map((data) => (
<Tab eventKey={data[0]} title={data[0]}> </Tab>
))}
</Tabs>
</div>
);
}
}
data[0] is the tabName.
Now, I would create custom tab, based on json value. For example, something, like this:
function DisplayCustomTab(props) {
return(
<div className="row">
<TabContainer className="mb-3">
<TabContent>
{Array.from(new Map(Object.entries(json))).map((data) => (
<>
{(() => {
if(myCondition ) {
return(
<>
<CreateTAB data={data[0]} />
</>
)
}
})()}
</>
))}
</TabContent>
</TabContainer>
</div>
);
}
function CreateTAB(props) {
console.log("tab name: " + props.data); // this line works
return(
<TabPane eventKey={props.data} title={props.data}> </TabPane>
);
}
I using TabPane, TabContent and TabContainer because using Tab and Tabs I get following error:
component is not meant to be rendered! It's an abstract component that is only valid as a direct Child of the `Tabs` Component. For custom tabs components use TabPane and TabsContainer directly
Anyone can explain where I'm wrong? Thank you

React Array not showing data in .map despite showing in console.log

I'm pulling in data from a GraphQL query and mapping through the array in my React app, I can see if I console log the array that all the data is there as requested but when I map through it, I just get nothing showing on my screen, no error, it doesn't generate any HTML elements or anything despite being similar to every other array map I've done so far.
My the mapping part of my component is as follows:
const CareerFeed = React.forwardRef((props, ref) => {
return (
<CareerFeedWrapper ref={ref}>
<Container width={14}>
{console.log(props.array)}
{props.array.map((item, index) => {
<CareerItem key={index}>
{item.title}
</CareerItem>
})}
</Container>
</CareerFeedWrapper>
)
})
You are not returning anything from the .map function: when you use curly brackets, the arrow function no longer implicitly returns. You will need to use the return statement:
{props.array.map((item, index) => {
return (
<CareerItem key={index}>
{item.title}
</CareerItem>
);
})}
Alternatively, ditch the curly brackets and wrap the returned JSX in parenthesis to take advantage of explicit returns:
{props.array.map((item, index) => (
<CareerItem key={index}>
{item.title}
</CareerItem>
))}
Looks like a missing return statement on the map. This means its actually iterating through the array and replacing each one with a null object. Try this:
return (
<CareerFeedWrapper ref={ref}>
<Container width={14}>
{console.log(props.array)}
{props.array.map((item, index) => {
return (<CareerItem key={index}> //added return
{item.title}
</CareerItem>) //added closing parentheses for return
})}
</Container>
</CareerFeedWrapper>
)
})

How can I map over an array, and have a button access the mapped array without being in the map

Project idea: Essentially a stackoverflow clone. I have a "question" (in my case a code error), and you can post potential solutions to that error.
My issue is while mapping over the array of of "solutions", my button is inside the map so it gets duplicated with every solution. How can I move the button outside the map but with it still having access to the mapped information?
This is in React, hooks.
Code:
{props.errors?.map((error, index) => (
<Card
key={index}
title={error.id}
extra={More}
style={{ width: 500 }}
>
<p>{error.errorMessage}</p>
<p>{error.errorType}</p>
{error.solutions.map((solution, index) => {
return (
<>
<SyntaxHighlighter
language={error.errorType.toLowerCase()}
style={rainbow}
>
{solution.solution}
</SyntaxHighlighter>
<Button
type="primary"
onClick={() => {
updateOn();
addSolution(solution);
}}
>
Add Solution
</Button>
</>
);
})}
</Card>
))}

How do I get the id or index of a card in a list?

I'm having trouble getting the id's for documents I've pulled from a MongoDB database and then displayed on a series of cards I've rendered using React and Material-Ui.
I've tried console-logging id in my functions and in the API's that I've set up, but I either get 'undefined', which is what the API returns, or a bunch of meta-data, which is what the delete function returns.
Here is my delete function:
handleDelete = id => {
console.log(id);
console.log(this.props.match.params);
// API.deleteArticle(this.props.match.params.id)
// .then(res => console.log(res.data))
// .catch(err => console.log(err));
// this.props.history.push("/saved");
};
Here is my API:
deleteArticle: function(id) {
console.log(id);
return axios.delete("/api/articles/" + id);
}
And here is how my card is rendered:
{this.state.savedArticles.length ? (
<Grid>
{this.state.savedArticles.map((oneSavedArticle, i) => (
<Card
style={savedArticleCard}
key={oneSavedArticle.id}
>
<Typography variant="h5">{oneSavedArticle.headline}</Typography>
<Divider variant="middle" />
<Typography>{oneSavedArticle.snippet}</Typography>
<a href={oneSavedArticle.web_url} style={linkStyles}>
<Button style={buttonStyles}>READ IT</Button>
</a>
<button onClick={this.handleDelete}>Delete</button>
{/* <DeleteDialogue id={props.articleFromDatabase.id} {...this.props} /> */}
</Card>
))}
</Grid>
) : (
The other part of that Ternary is just a default card that displays if the db is empty.
I'd like to be able to get the id so I can then delete the document from the database (and the card from the DOM).
Any help will be greatly appreciated. Many thanks in advance!
The problem is that you are not passing the ID to the handelDelete function, you need to update your code as follows:
{this.state.savedArticles.length ? (
<Grid>
{this.state.savedArticles.map((oneSavedArticle, i) => (
<Card
style={savedArticleCard}
key={oneSavedArticle.id}
>
<Typography variant="h5">{oneSavedArticle.headline}</Typography>
<Divider variant="middle" />
<Typography>{oneSavedArticle.snippet}</Typography>
<a href={oneSavedArticle.web_url} style={linkStyles}>
<Button style={buttonStyles}>READ IT</Button>
</a>
<button onClick={() => this.handleDelete(oneSavedArticle.id)}>Delete</button>
{/* <DeleteDialogue id={props.articleFromDatabase.id} {...this.props} /> */}
</Card>
))}
</Grid>
) : (
You don't pass the id to the handleDeleteFunction() here:
<button onClick={this.handleDelete}>Delete</button>
Thats why id is always undefined if you log it in handleDeleteFunction().
You have two options to pass the id properly.
Option 1: Use arrow function
<button onClick={() => this.handleDelete(oneSavedArticle.id)}>Delete</button>
Option 2: Use bind()
<button onClick={this.handleDelete.bind(this, oneSavedArticle.id)}>Delete</button>

Categories

Resources