How can I call a function inside of a .map of arrays? - javascript

I am passing down a function through props that capitalizes a few items being mapped over. I am getting an error on the item portion of item.creator.I am just wondering why I am recieving the error and not able to just call the function inside of the map. Thanks for your help.
Error message is Line Parsing error: Unexpected token, expected ",".
PARENT COMPONENT
export default function MainContent() {
const techContent = useSelector(displayTechContent);
const designContent = useSelector(displayDesignContent);
const makeCapital = (words) => words.replace(/^\w/, (c) => c.toUpperCase());
return (
<div className="container">
<div className="topics-list">
<div className="topic-row mb-5">
<h2 className="topic-heading mb-4">Software Development</h2>
<ContentCard data={techContent} capitalize={makeCapital} />
</div>
CHILD COMPONENT
export default (props) => (
<div>
<div className="resource-list">
{props.data.map((item) => (
<a key={item.id} href={item.link} className="resource-card-link mr-3">
<div className="card resource-card mb-2">
<div className="card-header">
<h4 className="resource-title">{item.title}</h4>
<span className="resource-creator">by: ***{props.capitalize({item.creator})}***.</span> <--this function
</div>
<div className="card-body py-3">
<div className="resource-description mb-2">
{item.description}
</div>
<div className="resource-type mb-2">
<i className="fas fa-book"></i> {item.type}
</div>

The curly braces around of item.creator are redundant.
export default (props) => (
<div>
<div className="resource-list">
{props.data.map((item) => (
<a key={item.id} href={item.link} className="resource-card-link mr-3">
<div className="card resource-card mb-2">
<div className="card-header">
<h4 className="resource-title">{item.title}</h4>
<span className="resource-creator">by: ***{props.capitalize(item.creator)}***.</span> <--this function
</div>
<div className="card-body py-3">
<div className="resource-description mb-2">
{item.description}
</div>
<div className="resource-type mb-2">
<i className="fas fa-book"></i> {item.type}
</div>

Related

Change boolean value onClick in React

I'm trying to change the value of a boolean from an object imported from a JSON file in React. I want the offers.availability value to change to false after clicking on the "add to cart" button.
Here's my code:
function App() {
class App {
constructor () {
this.state = {
offers: [],
}
this.handleToggle = this.handleToggle.bind(this);
}
componentDidMount() {
this.state.setState({ offers: Data });
}
handleToggle (offers) {
this.setState(prevState => ({
offers: prevState.offers.map(prevOffer => {
if (prevOffer.availability === offers.availability) {
return {
availability: prevOffer.availability,
isTrue: !prevOffer.isTrue
}
}
return prevOffer;
})}));
}
}
return (
<div className="container">
<div className="row">
{Data.offers.map(offers => {
return(
<div key={offers.make + offers.model + offers.engine + offers.photo} className="col-sm-4">
<div className="card" >
<img src={offers.photo} className="card-img-top" alt={offers.make + ' ' + offers.model } width="100%"/>
<div className="card-body pt-0 px-0">
<div className="d-flex flex-row justify-content-between mb-0 px-3 p-3 mid">
<div className="d-flex flex-column">
<h4>{offers.make} {offers.model}</h4>
</div>
<div className="d-flex flex-column">
<button type="button" className="btn btndelete"><FaTrash /></button>
</div>
</div>
<div className="d-flex flex-row justify-content-between px-3">
<div className="d-flex flex-column"><span className="text-muted">Engine: {offers.engine}</span></div>
<div className="d-flex flex-column">
{offers.availability.toString()}
</div>
</div>
<div className="mx-3 mt-3 mb-2 d-grid gap-2">
{offers.availability
? <button type="button" className="btn btn-primary addtocartbtn" onClick={() => Data.offers.handleToggle(offers)}>
<small>Add to cart</small>
</button>
: <button type="button" className="btn btn-disabled" onClick={console.log('???')}><small>Currently unavailabe</small></button>
}
</div>
</div>
</div>
</div>
)
}) }
</div>
</div>
)}
export default App;
I tried to toggle the boolean value but I currently get a ".offers.handleToggle is not a function" error after clicking.
I'm new to this so please don't judge if I did something really stupid here :) What could be the possible solution to this?
You should not use Data.offers.handleToggle. From what I see, Data.offers is an array of objects which they don't have a function handleToggle defined.
However, you are defining a function handleToggle on the App component that looks good. It should work if you change onClick={() => Data.offers.handleToggle(offers)} with either onClick={() => handleToggle(offers)} or onClick={() => this.handleToggle(offers)}
UPDATE
After running your code I saw the component is defined as a mix of a functional component and a class component. First, decide what you are going to use and then fix the errors 1 by 1. The constructor for example is missing the props, there are onclicks that are not well defined and a few more things.
Here is your code if used as a class component.
import { Component } from "react";
export class App extends Component<{}, { offers: any[] }> {
constructor(props: {}) {
super(props);
this.state = {
offers: [],
};
this.handleToggle = this.handleToggle.bind(this);
}
componentDidMount() {
this.setState({ offers: Data });
}
handleToggle(offers: any) {
this.setState((prevState) => ({
offers: prevState.offers.map((prevOffer) => {
if (prevOffer.availability === offers.availability) {
return {
availability: prevOffer.availability,
isTrue: !prevOffer.isTrue,
};
}
return prevOffer;
}),
}));
}
render() {
return (
<div className="container">
<div className="row">
{this.state.offers.map((offers) => {
return (
<div
key={offers.make + offers.model + offers.engine + offers.photo}
className="col-sm-4"
>
<div className="card">
<img
src={offers.photo}
className="card-img-top"
alt={offers.make + " " + offers.model}
width="100%"
/>
<div className="card-body pt-0 px-0">
<div className="d-flex flex-row justify-content-between mb-0 px-3 p-3 mid">
<div className="d-flex flex-column">
<h4>
{offers.make} {offers.model}
</h4>
</div>
<div className="d-flex flex-column">
<button type="button" className="btn btndelete">
<FaTrash />
</button>
</div>
</div>
<div className="d-flex flex-row justify-content-between px-3">
<div className="d-flex flex-column">
<span className="text-muted">
Engine: {offers.engine}
</span>
</div>
<div className="d-flex flex-column">
{offers.availability.toString()}
</div>
</div>
<div className="mx-3 mt-3 mb-2 d-grid gap-2">
{offers.availability ? (
<button
type="button"
className="btn btn-primary addtocartbtn"
onClick={() => this.handleToggle(offers)}
>
<small>Add to cart</small>
</button>
) : (
<button
type="button"
className="btn btn-disabled"
onClick={() => console.log("???")}
>
<small>Currently unavailabe</small>
</button>
)}
</div>
</div>
</div>
</div>
);
})}
</div>
</div>
);
}
}
You just need to define the offers type and a FaTrash component

Multiple items not displaying in my Cart [ReactJS]

am building a small E-commerce site, where I want to display the cart details but when I try to add more than one item to the cart, only one item will displaying in cart page.
How I coded for displaying items in Cart:
I have a (Home Page) HomePage.jsx, where i will display the all the products through API. and i have a Button VIEW DETAILS for earch Items.
clicking on VIEW DETAILS button will navigate to Another jsx component i.e. ProductDetails.jsx, where i will display products details with ADD TO CART button, when we click on that button, it will send a props to Header.jsx component for displaying Cart badge at the top. as well as sending its product ID as a props to Cart.jsx.
When user visit Cart.jsx page, we will fetching its product details based on products ID[send by props prev. step]
Please checkout this samall video:click
There is Nothing problem in HomePage and ProductDetails page, only facing in Cart
Homepage.jsx - Home Page - Displaying all products from API through map()
<div className="row ">
{
items.myItems.map((itm,index)=>(
<div className="col-sm justify-content-between position-relative d-flex flex-column align-items-center text-center">
<img src={itm.image} id={`thummbnail_id${itm.id}`} alt="" height="300" width="300" className="text-center thumbnail" />
<h4>{itm.title}</h4>
<p>Rs.{itm.price}</p>
<li className="btn mb-5 btn-primary"><Link className="text-white" to={`/products-details/${itm.id}`}>VIEW DETAILS</Link></li>
</div>
))
}
</div>
ProductDetails.jsx - Product Details - Displaying particular product details
<div className="row">
{
initData1.products.map((item,index)=>
{
if(getId!=item.id)
{
return <div className="col-sm justify-content-between position-relative d-flex flex-column align-items-center text-center">
<p>{index}</p>
<p>{item.id}</p>
<img src={item.image} id={`thummbnail_id${item.id}`} alt="" height="300" width="300" className="text-center thumbnail" />
<h4>{item.title}</h4>
<p>Rs.{item.price}</p>
<li className="btn mb-5 btn-primary"><Link className="text-white" to={`/products-details/${item.id}`}>VIEW DETAILS</Link></li>
</div>
}
}
)}
</div>
Header.jsx - Header for displaying cart Badge
import {useState,React,useEffect} from 'react'
import {Link} from 'react-router-dom'
import '../../src/head_cont.css'
function Header(props) {
return (
<div className="head_cont">
<div className="container">
<div className="left">
<li className="logo text-light">SHOP69</li>
</div>
<div className="right">
<ul>
<li className="header_links mx-4"><Link className="link" to="/">HOME</Link></li>
<Link to="/"><i class="fas cart_icon cart_icon_resp pt-4 text-white fa-2x fa-home"></i></Link>
{/* <li className="header_links mx-4"><a className="link" href="#container_id">PRODUCTS</a></li> */}
<li className="header_links mx-4"><Link className="link" to="/cart-details">VISIT STORE</Link></li>
<Link to="/cart-details"><i className=" cart_icon pt-4 fa-2x fas text-light fa-shopping-bag"></i>{props.text>=1 ? <span className="badge" id="badge">{props.text}</span> : ""}</Link>
</ul>
</div>
</div>
</div>
)
}
export default Header
CartDeails.jsx - Cart Page
import React from 'react'
import { useState, useEffect } from 'react'
import '../../src/cart-details.css'
function CartDetails(props) {
const[cart,setCart]=useState([])
useEffect(() => {
try
{
let id=props.id
fetch(`https://fakestoreapi.com/products/${id}`).then(function(res){
return res.json();
}).then(function(data){
console.log(data)
setCart([...cart,data])
})
}
catch(err)
{
console.log("Something went wrong while fetching Cart items")
}
}, [])
if(props.val>=1)
{
return (
<div>
{cart.map((item,index)=>(
<div className="cart_cont text-dark">
<div className="innerDiv row m-auto mt-4 d-flex shadow-lg container">
<div className="d-flex justify-content-around align-items-center flex-column col-sm d-flex id">
<label htmlFor="id" className="text-danger fw-bold m-auto">ID</label>
<p className="m-auto" id="id">{item.id}</p>
</div>
<div className="d-flex col-sm thumbnail">
<img src={item.image} className="mt-1 mb-1" alt="image" height="100px" width="80px"/>
</div>
<div className="d-flex align-items-center flex-column col-sm quantity">
<label htmlFor="title" className="text-danger fw-bold m-auto">Title</label>
<p className="m-auto" id="title">{item.title}</p>
</div>
<div className="d-flex align-items-center col-sm flex-column unitPrice">
<label htmlFor="unitprice" className="text-danger fw-bold m-auto">Unit Price</label>
<p className="m-auto unitprice" id="unitprice">Rs. {item.price}</p>
</div>
<div className="d-flex align-items-center flex-column col-sm total">
<label htmlFor="total" className="text-danger fw-bold m-auto">Total</label>
<p className="m-auto total" id="total">N/A</p>
</div>
<div className="d-flex align-items-center col-sm rmBtn">
<i class="far fa-2x m-auto fa-trash-alt"></i>
</div>
</div>
</div>
))
}
</div>
)
}
else
{
return (
<div className="no_items">
<div className="no_items_bg text-center">
<h2 className="display-5 fw-bold">Cart is Empty</h2>
<i class="fas fa-5x fa-cat"></i>
</div>
</div>
)
}
}
export default CartDetails
As am familiar with React Functional Component and whole code is given here.
Please help me.
Thanks in advance.

Uncaught TypeError: Cannot read property 'renderRows' of undefined

I am in the process of switching a component class to a function in my website so I can use hooks to interact with my backend, but after switching to the arrow function i am now getting the error above. What exactly changed to cause this error, I know i had to delete the render{} but is that what is causing it? Here is my current code where the error is located.
import React, { Component, useEffect, useState } from "react";
import ReactDOM from 'react-dom';
import { Link } from "react-router-dom";
import "./HomePageBody.scss";
import products from "../../../../back-end/products";
const HomePageBody = () => {
const getProducts = async() => {
try {
const response = await fetch("http://localhost:5000/carts");
const jsonData = await response.json();
console.log(jsonData);
} catch (err) {
console.error(err.message);
}
}
useEffect(() => {
getProducts();
});
let renderRows = () => {
let finalArr = [];
products.forEach((product) => {
finalArr.push(
<div className="col-md-6 col-lg-4 mt-4 colCard w-75">
<Link
to={{
pathname: "/ProductPage/" + product.name,
state: { sentproduct: product },
}}
>
<div className="card w-100 h-100">
<div className="card-img-wrap w-100 h-100">
<img
className=" card-img-top"
src={product.img}
alt="Card image cap"
/>
</div>
<div className="card-body">
<h6 className="card-title text-center">{product.name}</h6>
<p className="card-text text-center">
<small className="text-muted red">${product.price}</small>
</p>
</div>
</div>
</Link>
</div>
);
});
return finalArr;
}
return (
<div className="largebody ">
<div
id="carouselAd"
className="carousel slide carousel-custom"
data-ride="carousel"
>
<div className="carousel-inner">
<div className="carousel-item active">
<a href="#">
<img
className=""
src="https://res.cloudinary.com/ndc-images/image/upload/f_auto,fl_force_strip.preserve_transparency.progressive.sanitize,q_auto:best/media//blog/buy-affordable-high-quality-clothes-that-last-from-sustainable-brands.jpg"
alt="First slide"
/>
</a>
</div>
<div className="carousel-item">
<a href="#">
<img
className=""
src="https://res.cloudinary.com/ndc-images/image/upload/f_auto,fl_force_strip.preserve_transparency.progressive.sanitize,q_auto:best/media//blog/buy-affordable-high-quality-clothes-that-last-from-sustainable-brands.jpg"
alt="Second slide"
/>
</a>
</div>
<div className="carousel-item">
<a href="#">
<img
className=""
src="https://res.cloudinary.com/ndc-images/image/upload/f_auto,fl_force_strip.preserve_transparency.progressive.sanitize,q_auto:best/media//blog/buy-affordable-high-quality-clothes-that-last-from-sustainable-brands.jpg"
alt="Third slide"
/>
</a>
</div>
<div className="carsouselControls">
<a
className="carousel-control-prev"
href="#carouselAd"
role="button"
data-slide="prev"
>
<span
className="carousel-control-prev-icon"
aria-hidden="true"
></span>
<span className="sr-only">Previous</span>
</a>
<a
className="carousel-control-next"
href="#carouselAd"
role="button"
data-slide="next"
>
<span
className="carousel-control-next-icon color.red"
aria-hidden="true"
></span>
<span className="sr-only">Next</span>
</a>
</div>
</div>
</div>
<div className="col-lg-9 col-sm-12 m-auto">
<h1 className="text-center mt-5 mb-3 ml-auto mr-auto headerFont">
"Equality is the soul of liberty; there is, in fact, no liberty
without it." - Frances Wright
</h1>
<p className="paragraphFont">
We at EqualityFits believe that all people should be treated equaly
and fairly regarldess of race, religion, and sexuality. We support
groups such as Black Lives Matter and LBGTQ. Every one of our
products donates to an underlying organization that has to do with
that specific product. We believe that helping theses organizations
is a first step in total equality throughout society.
</p>
</div>
<div className="container cardbuttons text-center mb-5 mt-5">
<div className="row mt-5 inline-block">
<div className="col-lg-4 ml-auto">
<Link
to={{
pathname: "/Collections/" + "LGBT",
key: Math.random,
state: { sentinfo: "LGBT" },
}}
>
<div className="card">
<div className="card-img-wrap">
<img
className="card-img-top ml-auto mt-2 img"
src="http://equalityfits.com/img/menstshirt.png"
alt="Card image cap"
/>
</div>
</div>
</Link>
</div>
<div className="col-lg-4 ">
<Link
to={{
pathname: "/Collections/" + "LGBT",
key: Math.random,
state: { sentinfo: "LGBT", name: false, cat: true },
}}
>
<div className="card position-relative">
<div className="card-img-wrap right">
<img
className="card-img-top ml-auto mt-2 img"
src="http://equalityfits.com/img/menstshirt.png"
alt="Card image cap"
></img>
</div>
</div>
</Link>
</div>
<div className="col-lg-4 mr-auto">
<Link
to={{
pathname: "/Collections/" + "LGBT",
key: Math.random,
state: { sentinfo: "LGBT", name: false, cat: true },
}}
>
<div className="card">
<div className="card-img-wrap">
<img
className="card-img-top mr-auto mt-2 img"
src="http://equalityfits.com/img/womenstshirt.png"
alt="Card image cap"
/>
</div>
</div>
</Link>
</div>
</div>
</div>
<div className="row ml-auto mr-auto mt-5 w-75">
<div className="col-lg-9 col-sm-12 m-auto p-0 mt-5">
<h1
className="text-center font-weight-bold mt-5"
style={{ marginLeft: "9px" }}
>
Best Selling
</h1>
<hr style={{ borderTop: "3px solid rgba(0, 0, 0, 0.1)" }}></hr>
<div className="row justify-content-center">
**{this.renderRows()}** <-----------------Where i call upon the function
</div>
</div>
</div>
</div>
);
}
export default HomePageBody;
I call upon the function at the bottom, i put arrows next to it to make it easier.
You are no longer in a class, so the this context no longer makes sense. Just change it to renderRows().
renderRows is no longer a method on you class, but rather a function in your component. Therefore instead of this.renderRows(), you call it using renderRows().

Refactoring jQuery for react component

I am moving away from using jQuery to do some quick hides, shows and css changes because I am using components in react that need to be re-rendered and thus are not triggering the jQuery actions that need a page refresh. I think my issue is that I need to set the state in each component but I am a bit confused as to how. Here is an example of the jquery for this particular view:
<script type="text/javascript">
$(document).ready(function () {
$(".schedule-times").hide();
$(".final-check").hide();
$(".available-time").on('click', function () {
$(".schedule-times").toggle();
});
$(".schedule-button").on('click', function () {
$('.finalize-timeline').css("background", "#4CAF50");
$(".final-check").show();
});
});
</script>
Here is an example of a component I have written:
import React, { Component } from 'react';
import '../../App.css';
import Calendar from '../Calendar';
import { Link } from 'react-router';
class Schedule_3 extends Component {
render() {
return (
<div className="wow fadeIn">
<div className="container">
<div className="timeline">
<div className="col-md-12 offset-md-2">
<div className="row">
<div className="col-md-2 timeline-box">
<div className="timeline-badge active-timeline">
<i className="fa fa-check wow bounceInDown"></i>
</div>
<span>How do you want to schedule?</span>
</div>
<div className="col-md-2 timeline-box">
<div className="timeline-badge active-timeline">
<i className="fa fa-check wow bounceInDown"></i>
</div>
<span>Pick your lesson type</span>
</div>
<div className="col-md-2 timeline-box">
<div className="timeline-badge active-timeline">
</div>
<span>Find a time</span>
</div>
<div className="col-md-2 timeline-box">
<div className="timeline-badge" id="no_border">
</div>
<span>Finalize</span>
</div>
</div>
</div>
</div>
<div className="row">
<div className="container">
<div className="col-md-6 offset-md-3">
<Calendar />
</div>
</div>
</div><br />
<div className="row schedule-times">
<div className="col-md-12 offset-md-2">
<div className="row">
<div className="col-md-4 offset-md-1">
<i className="fa fa-clock"></i>
10:30AM
</div>
<div className="col-md-2 offset-md-1">
<Link to="Schedule_4">
<button className="btn btn-primary">
Book Now
</button>
</Link>
</div>
</div><br />
<div className="row">
<div className="col-md-4 offset-md-1">
<i className="fa fa-clock"></i>
11:00AM
</div>
<div className="col-md-2 offset-md-1">
<button className="btn btn-primary">
Book Now
</button>
</div>
</div><br />
<div className="row">
<div className="col-md-4 offset-md-1">
<i className="fa fa-clock"></i>
11:30AM
</div>
<div className="col-md-2 offset-md-1">
<button className="btn btn-primary">
Book Now
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Schedule_3;
Looking at your code I would suggest the first thing you need to do is split it into smaller, more manageable and more readable components that are responsible for 1 thing.
As you have posted a big example I cannot show you how to do it for every case you have, but I can give you a simple example that can be adapted for your use cases.
class ToggleContent extends React.Component {
constructor() {
super();
this.state = { hidden: true };
this.toggleContent = this.toggleContent.bind(this);
}
toggleContent() {
this.setState(prevState => ({
hidden: !prevState.hidden
}));
}
render() {
const { hidden } = this.state;
const { children } = this.props;
return (
<div>
<button onClick={ this.toggleContent }>Toggle</button>
<div>
{ !hidden && children }
</div>
</div>
);
}
}
You can use this component like this <ToggleContent>Hello World</ToggleContent> and it will toggle visibility of Hello World on the button press. You can put anything inside of this, including other components, it doesn't have to just be text.
You can see an example of it running here.
You can see the state of whether the children are hidden or not is held in the component this.state = { hidden: true };.
The children are then rendered if it is not hidden, if !hidden === true. We can see that inline here { !hidden && children }.
The toggleContent method is then using the previous state to switch back and forth between hidden and showing.
toggleContent() {
this.setState(prevState => ({
hidden: !prevState.hidden
}));
}

How can I get a dynamic value of href and id's of the card in React JS

This is my first question in stackoverflow, I am still learning how to code and it might be a newbie question.
But, is it possible to have a dynamic href and id values when I want to map my data with axios to become cards? Because if I run my code, the card that will work (one that can collapse) is just the first one, the others did not work. This is my code (sorry the code isnt the same with the real file in my vscode cos my real file was becoming a chaos.)
render() {
const mobillist = this.state.dataku.map((item, index) => {
return (
<div className="container-fluid" style={{ marginTop: "100px" }}>
<div id="accordion">
<div className="card">
<div className="card-header">
<a className="card-link" data-toggle="collapse" href="#colla">
{item.model} - {item.tahun}
</a>
</div>
<div id="colla" className="collapse show" data-parent="#accordion">
<div className="card-body">
<div className="row">
<div className="col">
<h4> ini menu 1 </h4>
</div>
<div className="col">
<center> <h4> ini menu 2 </h4></center>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
return (
<div>
{mobillist}
</div>
You can use unique ID for every href using index value in the map and also map the index in accordion div. See the below code for sample
render() {
const mobillist = this.state.dataku.map((item, index) => {
return (
<div className="container-fluid" style={{ marginTop: "100px" }}>
<div id="accordion">
<div className="card">
<div className="card-header">
<a className="card-link" data-toggle="collapse" href={"#colla"+ index}>
{item.model} - {item.tahun}
</a>
</div>
<div id={"colla"+ index} className="collapse show" data-parent="#accordion">
<div className="card-body">
<div className="row">
<div className="col">
<h4> ini menu 1 </h4>
</div>
<div className="col">
<center> <h4> ini menu 2 </h4></center>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
return (
<div>
{mobillist}
</div>

Categories

Resources