This is the code where I have my addtocart function,
import React from 'react'
import './Body.css'
import { useState } from 'react'
// import './Cart.js'
export default function Pricetag(props) {
const [count, setCartCount] = useState(0)
return (
<div>
<div className="cart">
<i class="fa-solid fa-cart-shopping"></i>
<div id="number">=</div>
</div>
<div className="card1">
<div className="image">
<img src={props.images} alt="" className='card-image' />
</div>
<div className="content">
<div className="name">
{props.name}
</div>
</div>
<div className="button">
<button className='btn no1' id='cartbutton' onClick={() => setCartCount( count +1)} >
{/* <a id="cart" href="https://wa.me/<919650988301>" target='_blank' rel="noreferrer" className='no1'>Add to cart</a></button> */}
Add to cart </button>
</div>
</div>
<script ></script>
</div>
)
}
When I do,
number.innerHTML+=`${items}`
instead of
number.innerHTML=`${items}`
then the numbers are concatenated like strings.
Otherwise, nothing is happening, what is wrong here?
Can you suggest me some edits in the same code.
As you are using React framework you should use React hooks
Here is an example:
import React, { useState } from 'react'
import './Body.css'
// import './Cart.js'
export default function Pricetag(props) {
const [cartCount, setCartCount] = useState(0)
return (
<div>
<div className="cart">
<i class="fa-solid fa-cart-shopping"></i>
<div id="number">={cartCount}</div>
</div>
<div className="card1">
<div className="image">
<img src={props.images} alt="" className='card-image' />
</div>
<div className="content">
<div className="name">
{props.name}
</div>
</div>
<div className="button">
<button className='btn no1' id='cartbutton' onClick={() => setCartCount(cartCount +1))} >
{/* <a id="cart" href="https://wa.me/<919650988301>" target='_blank' rel="noreferrer" className='no1'>Add to cart</a></button> */}
Add to cart </button>
</div>
</div>
</div>
)
}
Working on codesandbox
Related
import React, { useEffect } from "react";
import Loader from "../layout/Loader";
import { useAlert } from "react-alert";
import { useDispatch, useSelector } from "react-redux";
import { getProductDetails, clearErrors } from "../../actions/productActions";
const ProductDetails = ({ match }) => {
const dispatch = useDispatch();
const alert = useAlert();
const { loading, error, product } = useSelector((state) =>
state.productDetails()
);
useEffect(() => {
dispatch(getProductDetails());
if (error) {
alert.error(error);
dispatch(clearErrors());
}
}, [dispatch, alert, error]);
return (
<>
{!loading ? (
<Loader />
) : (
<>
<div className='row f-flex justify-content-around'>
<div className='col-12 col-lg-5 img-fluid' id='product_image'>
<img
src='https://i5.walmartimages.com/asr/1223a935-2a61-480a-95a1-21904ff8986c_1.17fa3d7870e3d9b1248da7b1144787f5.jpeg?odnWidth=undefined&odnHeight=undefined&odnBg=ffffff'
alt='sdf'
height='500'
width='500'/>
</div>
<div className='col-12 col-lg-5 mt-5'>
<h3>{product.name}</h3>
<p id='product_id'>Product # sklfjdk35fsdf5090</p>
<hr />
<div className='rating-outer'>
<div className='rating-inner'></div>
</div>
<span id='no_of_reviews'>(5 Reviews)</span>
<hr />
<p id='product_price'>$108.00</p>
<div className='stockCounter d-inline'>
<span className='btn btn-danger minus'>-</span>
<input
type='number'
className='form-control count d-inline'
value='1'
readOnly
/>
<span className='btn btn-primary plus'>+</span>
</div>
<button
type='button'
id='cart_btn'
className='btn btn-primary d-inline ml-4'
>
Add to Cart
</button>
<hr />
<p>
Status: <span id='stock_status'>In Stock</span>
</p>
<hr />
<h4 className='mt-2'>Description:</h4>
<p>
Binge on movies and TV episodes, news, sports, music and more!
We insisted on 720p High Definition for this 32" LED TV,
bringing out more lifelike color, texture and detail. We also
partnered with Roku to bring you the best possible content with
thousands of channels to choose from, conveniently presented
through your own custom home screen.
</p>
<hr />
<p id='product_seller mb-3'>
Sold by: <strong>Amazon</strong>
</p>
<button
id='review_btn'
type='button'
className='btn btn-primary mt-4'
data-toggle='modal'
data-target='#ratingModal'
>
Submit Your Review
</button>
<div className='row mt-2 mb-5'>
<div className='rating w-50'>
<div
className='modal fade'
id='ratingModal'
tabIndex='-1'
role='dialog'
aria-labelledby='ratingModalLabel'
aria-hidden='true'
>
<div className='modal-dialog' role='document'>
<div className='modal-content'>
<div className='modal-header'>
<h5 className='modal-title' id='ratingModalLabel'>
Submit Review
</h5>
<button
type='button'
className='close'
data-dismiss='modal'
aria-label='Close'
>
<span aria-hidden='true'>×</span>
</button>
</div>
<div className='modal-body'>
<ul className='stars'>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
</ul>
<textarea
name='review'
id='review'
className='form-control mt-3'
></textarea>
<button
className='btn my-3 float-right review-btn px-4 text-white'
data-dismiss='modal'
aria-label='Close'
>
Submit
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)}
</>
);
};
export default ProductDetails;
As the error suggests
state.productDetails is not a function
This is because productDetails is a reducer object and Not a function created by redux. Hence, your code should be
const { loading, error, product } = useSelector((state) =>state.productDetails); //Note: productDetails without '()'
Hope it helps.
Side Note: While posting any question or answer please format the code properly next time so it's readable. :)
Im mapping through some context.api data, and displaying that data on a page. this works fine. However, when i want to send a piece of that array.map back to the context for state management, it only chooses the last item. I want it to choose the item you click on.
Code:
import { React, useState, useEffect, useContext } from "react";
import { DataContext } from "../contexts/dataContext";
import { Link } from "react-router-dom";
const Example = () => {
const [open, setOpen] = useState(false);
const [input, setInput] = useState(null);
const[designation, setDesignation] = useState(null);
const { data } = useContext(DataContext);
const { onChange } = useContext(DataContext);
const { onClick} = useContext(DataContext);
return(
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-6 col-md-6 col-lg-6 col-xl-6 col-xxl-6 offset-sm-3 offset-md-3 offset-lg-3 offset-xl-3 offset-xxl-3 min-vh-100 text-center p-5 border">
{
data.map((item) => {
return(
<div className='row' key={item.id}>
<div className='col-xs-12 placeholder placeholder_image rounded'></div>
<div className='col-xs-12 text-start p-0 pt-2 m-0'>
<h2>{item.title}</h2>
<p>
<div className='col-sm-11'>
<a className="no_underline link-dark" data-bs-toggle="collapse" href={item.dataTarget} role="button" aria-expanded="false" aria-controls="collapseExample">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam venenatis sapien...<i className="bi bi-caret-down-fill"></i></a>
</div>
</p>
<div className="collapse" id={item.dataId}>
<div>
<p>{item.text}</p>
</div>
<form>
<div className='row mt-2 mb-2'>
<div className='d-grid gap-2 col-8 mx-auto'>
<div className="form-floating text-start">
<input type="text" className="form-control" id="enterAmount" placeholder='Enter Amount' aria-describedby="enterAmount" onChange={e => {setInput(e.target.value);onChange(e.target.value);}} />
<label htmlFor="enterAmount">Enter Amount</label>
</div>
</div>
</div>
<div className='row mt-2 mb-2'>
<div className='d-grid gap-2 col-6 mx-auto'>
<Link to="/checkout" className="btn btn-lg button-color" onClick={ onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link>
</div>
</div>
</form>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
)
}
export default Example
This is the part that i am using to get the data:
<Link to="/checkout" className="btn btn-lg button-color" onClick={ onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link>
the onClick function in my context api looks like this:
const[designation, setDesignation] = useState(null);
its just a setState function really.
So why is it that every time its set, its returning the third title in a 3 item array?
Change onClick event on Link to this.
<Link to="/checkout" className="btn btn-lg button-color" onClick={() =>onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link> –
onClick takes a function, but you’re passing it the value of calling a function.
The function gets called on each iteration, which updates the state each time and ultimately state settles in the last item’s onClick call.
Try this:
onClick={() => onClick(item.name)}
My cart.jsx is below
Getting this error while compiling react js
error is comingin line 16 Object.keys(basketPro....enter image description here
My cart.jsx is below
Getting this error while compiling react js
error is comingin line 16 Object.keys(basketPro....enter image description here
My cart.jsx is below
Getting this error while compiling react js
error is comingin line 16 Object.keys(basketPro....enter image description here
import React, {Fragment} from 'react';
import "../css/cart.css";
import loc from "../images/loc.svg";
import "../css/home.css";
import img1 from "../images/1.jpeg";
import fassured from "../images/fassured.jpg";
import {ProductQuantity, ClearProduct} from "./ProductQuantity";
import { connect } from 'react-redux';
const Cart = ({basketProps, ProductQuantity, ClearProduct}) =>
{
console.log(basketProps);
let productsInCart = [];
Object.keys(basketProps.products).forEach( function(item) {
console.log(item);
console.log(basketProps.products[item].inCart);
> Blockquote
if(basketProps.products[item].inCart) {
productsInCart.push(basketProps.products[item])
}
console.log(productsInCart);
});
const productImages = (product) => {
if(product.tagname === "sonyTv") {
return img1;
}
};
productsInCart = productsInCart.map((product, index)=> {
console.log("My product is");
console.log(product);
return (
<Fragment key={index}>
<div className="cart">
<div className="item_detail">
<div className="cart_header">
<div className="header_left">
<p> My Cart (1) </p>
</div>
<div className="header_right">
<p> <img src={productImages(product)}/> </p>
<p> Deliver to <span> Bangalore - 560006 </span> </p>
</div>
</div>
<div className="cart_body">
<div className="body_left">
<div className="cart_top">
<div className="cart_img">
<img src={img1} />
</div>
<div className="cart_deta">
<p> {product.name} </p>
<p> Seller: OmniTechRetail <img src={fassured}/> </p>
<p> ₹{product.price} </p>
</div>
</div>
<div className="cart_bottom">
<div>
<p onClick={() => ProductQuantity("decrease", product.tagname)}> - </p>
<p> {product.numbers} </p>
<p onClick={() => ProductQuantity("increase", product.tagname)}> + </p>
</div>
<div onClick={()=> ClearProduct(product.tagname)}> <p> REMOVE </p> </div>
</div>
</div>
<div className="body_right">
<p> Delivery by 11 Am, Tomorrow | </p>
<p> ₹ 25 </p>
</div>
</div>
<div className="cart_footer">
<button className="place_order">
PLACE ORDER
</button>
</div>
</div>
<div className="price_detail">
<div> PRICE DETAILS </div>
<div className="price">
<div className="spa_bet"> <div> Price (1 item) </div> <div> ₹67,999 </div></div>
<div className="spa_bet"> <div> Discount </div> <div> -₹4,000 </div></div>
<div className="spa_bet"> <div> Delivery Charges </div> <div> ₹25 </div></div>
</div>
<div className="total">
<div> Total Amount </div>
<div> ₹{product.numbers*product.price} </div>
</div>
<div className="saved">
<p> You will save ₹26,901 on this order </p>
</div>
</div>
</div>
</Fragment>
)
});
return (
<>
{productsInCart}
</>
);
};
const mapStateToProps = state => ({
basketProps: state.basketState
});
export default connect(mapStateToProps, { ProductQuantity, ClearProduct } )(Cart);
There is a problem with your code: code executes without checking the availability of data.
And I also recommend you to use useState and useEffect as a ReactJS programmer always do like below
import React, {Fragment, useState, useEffect} from 'react';
const Cart = ({basketProps, ProductQuantity, ClearProduct}) =>{
const [productsInCart, setProductInCart] = useState([]);
useEffect(()=>{
if(basketProps?.products){
let tempProduct = [];
Object.keys(basketProps.products).forEach( function(item) {
if(basketProps.products[item].inCart) {
tempProduct.push(basketProps.products[item])
}
console.log(tempProduct);
});
setProductInCart(tempProduct);
}
}, [])
And the same with below code, check availability too.
productsInCart = ()=>{
return ( !productsInCart.length ? "" :
productsInCart.map((product, index)=> {
return (
<Fragment key={index}>
<div className="cart">
<div className="item_detail">
<div className="cart_header">
<div className="header_left">
<p> My Cart (1) </p>
</div>
<div className="header_right">
<p> <img src={productImages(product)}/> </p>
<p> Deliver to <span> Bangalore - 560006 </span> </p>
</div>
</div>
<div className="cart_body">
<div className="body_left">
<div className="cart_top">
<div className="cart_img">
<img src={img1} />
</div>
<div className="cart_deta">
<p> {product.name} </p>
<p> Seller: OmniTechRetail <img src={fassured}/> </p>
<p> ₹{product.price} </p>
</div>
</div>
<div className="cart_bottom">
<div>
<p onClick={() => ProductQuantity("decrease", product.tagname)}> - </p>
<p> {product.numbers} </p>
<p onClick={() => ProductQuantity("increase", product.tagname)}> + </p>
</div>
<div onClick={()=> ClearProduct(product.tagname)}> <p> REMOVE </p> </div>
</div>
</div>
<div className="body_right">
<p> Delivery by 11 Am, Tomorrow | </p>
<p> ₹ 25 </p>
</div>
</div>
<div className="cart_footer">
<button className="place_order">
PLACE ORDER
</button>
</div>
</div>
<div className="price_detail">
<div> PRICE DETAILS </div>
<div className="price">
<div className="spa_bet"> <div> Price (1 item) </div> <div> ₹67,999 </div></div>
<div className="spa_bet"> <div> Discount </div> <div> -₹4,000 </div></div>
<div className="spa_bet"> <div> Delivery Charges </div> <div> ₹25 </div></div>
</div>
<div className="total">
<div> Total Amount </div>
<div> ₹{product.numbers*product.price} </div>
</div>
<div className="saved">
<p> You will save ₹26,901 on this order </p>
</div>
</div>
</div>
</Fragment>
)
}))};
The data variable contains all the data needed for this operation the problem is that the frontend shows card one below the other whereas I want it to show 3 or 4 in one row. I can assure that the error is not with the react or the graphql, the error is in the bootstrap or the way I am rendering the data.
I just want a responsive design so at first i have created a html css bootstrap ui which was perfectly working and was responsive but when i combined it with the data it lost its responsiveness and now it shows cards one below the other.
here is the image of how it is currentlyIt shows that there is a card but no other card along the row
Here is my code:
import React, { useState } from "react";
import { gql, useQuery } from "#apollo/client";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const getBooksQuery = gql`
{
books {
name
id
genre
author {
name
}
description
rating
image
}
}
`;
function BooksDisplay() {
const { loading, error, data } = useQuery(getBooksQuery);
var [selected, setSelected] = useState("");
if (loading) return <p>Loading....</p>;
if (error) return <p>Ops! Something went wrong</p>;
return (
<div>
<div id="book-list">
{data.books.map((book) => (
<div className="container-fluid my-5 books_section">
<div className="row">
<div className="col-xl-3 col-lg-4 col-sm-6 col-12 mt-4">
<div className="card h-100">
<img src={book.image} className="card-img-top" alt="..." />
<div className="card-body">
<h5 className="card-title font-weight-bold text-secondary">
{book.name}
</h5>
<span className="card-text">
{book.description}
<div className="collapse m-0" id="collapseExample">
<div className="card card-body border-0 p-0">
{book.description}
</div>
</div>
</span>
<a
className="card-link d-block"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample">
See More
</a>
</div>
<ul className="list-group list-group-flush">
<li className="list-group-item">
Authors:
<span>
{book.author.map((author) => author.name).join(" ")}
</span>
</li>
<li className="list-group-item">
Genre: <span>{book.genre.join(" ")}</span>
</li>
<li className="list-group-item">
Ratings: <span>{book.rating}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
))}
</div>
{/* <BookDetail bookid={selected} /> */}
</div>
);
}
function BookList() {
return (
<div>{BooksDisplay()}</div>
);
}
export default BookList;
You need to iterate the columns instead of the container...
import React, { useState } from "react";
import { gql, useQuery } from "#apollo/client";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const getBooksQuery = gql`
{
books {
name
id
genre
author {
name
}
description
rating
image
}
}
`;
function BooksDisplay() {
const { loading, error, data } = useQuery(getBooksQuery);
var [selected, setSelected] = useState("");
if (loading) return <p>Loading....</p>;
if (error) return <p>Ops! Something went wrong</p>;
return (
<div>
<div id="book-list">
<div className="container-fluid my-5 books_section">
<div className="row">
{data.books.map((book) => (
<div className="col-xl-3 col-lg-4 col-sm-6 col-12 mt-4">
<div className="card h-100">
<img src={book.image} className="card-img-top" alt="..." />
<div className="card-body">
<h5 className="card-title font-weight-bold text-secondary">
{book.name}
</h5>
<span className="card-text">
{book.description}
<div className="collapse m-0" id="collapseExample">
<div className="card card-body border-0 p-0">
{book.description}
</div>
</div>
</span>
<a
className="card-link d-block"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample">
See More
</a>
</div>
<ul className="list-group list-group-flush">
<li className="list-group-item">
Authors:
<span>
{book.author.map((author) => author.name).join(" ")}
</span>
</li>
<li className="list-group-item">
Genre: <span>{book.genre.join(" ")}</span>
</li>
<li className="list-group-item">
Ratings: <span>{book.rating}</span>
</li>
</ul>
</div>
</div>
))}
</div>
</div>
</div>
{/* <BookDetail bookid={selected} /> */}
</div>
);
}
function BookList() {
return (
<div>{BooksDisplay()}</div>
);
}
export default BookList;
Just put these 2 tags out of the loop
< div className="container-fluid my-5 books_section">
< div className="row">
And it will work.
I get API data in DownloadsHistory.jsx and passed props in the child components like below code:
<DownloadData
downloadToday={d.today}// need that separatly
downloadYesterday={d.yesterday}
downloadLastWeek={d.last_week}
downloadAllTime={d.all_time}
/>
If I console in DownloadData.jsx get below data:
{downloadToday: "55628", downloadYesterday: "98569", downloadLastWeek: "720570", downloadAllTime: "143086901"}
I get all the props data if I called <DownloadHistory/>. that's fine but how can I get single data from it? Suppose I want only {this.props.downloadToday}. on a third.jsx
Add more details code below:
DownloadHistory.jsx
import React, { Component } from "react";
import axios from "./axios";
import DownloadData from "./download-view";
class DownloadsHistory extends Component {
state = {
data: [],
};
componentDidMount() {
var slug = "contact-form";
const url =
"https://api.xyz.com/downloads.php?slug=" +
slug +
"&limit=10&historical_summary=1";
axios.get(url).then((res) => {
this.setState({ data: res.data });
});
}
constructor(props) {
super(props);
this.state = {};
}
render() {
var d = this.state.data;
if (!d) return <div className="loading"></div>;
return (
<div>
<DownloadData
downloadToday={d.today}
downloadYesterday={d.yesterday}
downloadLastWeek={d.last_week}
downloadAllTime={d.all_time}
/>
</div>
);
}
}
export default DownloadsHistory;
download-view.jsx
import React, { Component, Fragment } from "react";
class DownloadData extends Component {
render() {
console.log(this.props);
return (
<Fragment>
<table className="table" style={{ fontSize: 13, textAlign: "left" }}>
<tbody>
<tr>
<td>Today</td>
<td>{this.props.downloadToday}</td>
</tr>
<tr>
<td>Yesterday</td>
<td>{this.props.downloadYesterday}</td>
</tr>
<tr>
<td>Last Week</td>
<td>{this.props.downloadLastWeek}</td>
</tr>
<tr>
<th>All Time</th>
<th>{this.props.downloadAllTime}</th>
</tr>
</tbody>
</table>
</Fragment>
);
}
}
export default DownloadData;
widget.jsx
import React, { Fragment, Component } from "react";
import { faStar, faCheck } from "#fortawesome/free-solid-svg-icons";
import DownloadsHistory from "./DownloadsHistory";
import ActiveVersion from "./active-version";
import Downloads from "./download";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
class Widget extends Component {
render() {
console.log(this.props);
return (
<Fragment>
<div className="row mt-5">
<div className="col-lg-3 col-md-3">
<div className="widget text-center">
<div className="widget-heading clearfix">
<div className="pull-left">Download Today</div>
</div>
<div className="widget-body clearfix pt-0">
<div className="pull-left">
<FontAwesomeIcon icon={faCheck} color="#28a745" />
</div>
<div className="pull-right number">
<DownloadsHistory /> {/* Need only Today Data here*/}
</div>
</div>
</div>
</div>
<div className="col-lg-3 col-md-3">
<div className="widget text-center">
<div className="widget-heading clearfix">
<div className="pull-left">Download History</div>
</div>
<div className="widget-body clearfix pt-0">
<DownloadsHistory /> {/* okay here */}
</div>
</div>
</div>
<div className="col-lg-3 col-md-3">
<div className="widget text-center">
<div className="widget-heading clearfix">
<div className="pull-left">Active Install</div>
</div>
<div className="widget-body clearfix pt-0">
<div className="pull-left">
<FontAwesomeIcon icon={faCheck} color="#28a745" />
</div>
<div className="pull-right number">
{this.props.active_installs}+
<div style={{ fontSize: 13 }}>
but less than {this.props.probable_active_install}
</div>
</div>
</div>
</div>
</div>
<div className="col-lg-3 col-md-3">
<div className="widget text-center">
<div className="widget-heading clearfix">
<div className="pull-left">Average Ratings</div>
</div>
<div className="widget-body clearfix">
<div className="pull-left">
<FontAwesomeIcon icon={faStar} color="#28a745" />
</div>
<div className="pull-right number">{this.props.AvgRating}</div>
<div style={{ fontSize: 13 }}>
based on {this.props.number_of_rating} reviews
</div>
</div>
</div>
</div>
<div className="col-lg-3 col-md-3">
<div className="widget text-center">
<div className="widget-heading clearfix">
<div className="pull-left">Download History</div>
</div>
<div className="widget-body clearfix pt-0">
<DownloadsHistory />
</div>
</div>
</div>
<div className="col-lg-6 col-md-6">
<div className=" text-center">
<div className="clearfix">
<div className="pull-left">Active version</div>
</div>
<div className="clearfix pt-0">
<ActiveVersion />
</div>
</div>
</div>
</div>
</Fragment>
);
}
}
export default Widget;
** widget.jsx has some props from another parent.
Form your description I'm assuming that the DownloadData component is being rendered inside the DownloadHistory component. If it's the case, then you can simply place the Third component along with the DownloadData component and pass the downloadToday={d.today} only into the Third component.
Like this:
<DownloadData
downloadToday={d.today}// need that separatly
downloadYesterday={d.yesterday}
downloadLastWeek={d.last_week}
downloadAllTime={d.all_time}
/>
<Third downloadToday={d.today} />
Hope this will help.
You need to call the web service from the parent of both and pass the props to components.