Map doesn't work after setState after fetch - javascript

Could someone maybe explain why my map doesn't work in the template.
I tried 4 hours, but i didn't get a useful solution.
The render() works bevor i fetched all data from firebase
If i try to render the map again by using the setState Hook or in my case the setsalesList hook the templet doesn't render again.
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import NavBar from "./NavBar";
import { db } from "../firebase";
import { useAuth } from "../contexts/AuthContext";
const Sales = () => {
const [isLoading, setIsLoading] = useState(true);
const [salesList, setSalesList] = useState([]);
const { currentUser } = useAuth();
async function setupProject() {
let salesDataList = [];
await db
.collection("users")
.doc(currentUser.uid)
.get()
.then((userItemData) => {
const userItem = userItemData.data();
db.collection("projects")
.doc(userItem.project[0])
.get()
.then((projectData) => {
db.collection("sales")
.where("project", "==", projectData.id)
.get()
.then((sales) => {
sales.forEach((sale) => {
sale
.data()
.customer.get()
.then((customer) => {
let salesData = {
key: sale.id,
name: customer.data().name,
sold: sale.data().sold,
date:
new Date(sale.data().time.toDate()).getDate() +
"." +
new Date(sale.data().time.toDate()).getMonth() +
"." +
+new Date(sale.data().time.toDate()).getFullYear(),
};
salesDataList.push(salesData);
console.log(salesDataList);
});
});
setSalesList(salesDataList);
})
.finally(() => {});
});
});
setIsLoading(false);
}
useEffect(() => {
setupProject();
}, []);
return (
<>
<NavBar />
<div className="header header-fixed header-logo-center">
<a className="header-title">Verkäufe</a>
<a href="https://huehnerpi.de/customer" className="header-icon">
<i className="fas fa-user" />
</a>
<a
href="https://huehnerpi.de/sales/newSale"
className="header-icon header-icon-4"
>
<i className="fas fa-plus" />
</a>
</div>
{isLoading ? (
<div className="page-content header-clear-medium">
<div
className="content mt-0"
style={{
marginBottom: 16,
marginLeft: 16,
marginRight: 16,
}}
>
<p>Lädt...</p>
</div>
</div>
) : (
<div className="page-content header-clear-medium">
<div
className="card card-style"
style={{
marginBottom: "16px",
}}
>
<div className="content mb-0">
<div className="input-style input-style-always-active has-borders no-icon">
<select
id="dropdownStatus"
style={{
color: "darkslategray",
}}
>
<option value="all">Alle Status</option>
</select>
<span>
<i className="fa fa-chevron-down" />
</span>
<i className="fa fa-check disabled valid color-green-dark" />
<em />
</div>
<div className="input-style input-style-always-active has-borders no-icon">
<select
id="dropdownCustomer"
style={{
color: "darkslategray",
}}
>
<option value="all">Alle Käufer</option>
</select>
<span>
<i className="fa fa-chevron-down" />
</span>
<i className="fa fa-check disabled valid color-green-dark" />
<em />
</div>
</div>
</div>
{console.log(salesList.length)}
{salesList.map((saleItem) => (
<a
key={saleItem.key}
className="card card-style mb-3 filterDiv"
style={{ display: "block" }}
>
<div className="content">
<h3>
{saleItem.name} - {saleItem.sold} Eier
<span data-menu="menu-contact-2" style={{ float: "right" }}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-red-dark">
<i className="fas fa-times" />
</span>
</span>
<span style={{ float: "right" }}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-blue-dark">
<i className="fas fa-pen" />
</span>
</span>
</h3>
<div className="row mb-n2 color-theme">
<div className="col font-10 text-start">
<span className="badge bg-green-dark color-white font-10 mt-2">
Bezahlt
</span>
</div>
<div className="col font-10 text-end opacity-30">
<i className="fa fa-calendar pe-2" />
12.12.2020 <span className="copyright-year" />
</div>
</div>
</div>
</a>
))}
</div>
)}
</>
);
};
export default Sales;

In this way it worked now for me!
I set the state after the last iteration of my foreach
import {Link} from "react-router-dom";
import NavBar from "./NavBar";
import {db} from "../firebase"
import {useAuth} from "../contexts/AuthContext";
const Sales = () => {
const [isLoading, setIsLoading] = useState(true);
const [salesList, setSalesList] = useState([]);
const { currentUser } = useAuth();
function setupProject() {
let salesDataList = [];
db.collection("users").doc(currentUser.uid).get()
.then(userItemData => {
const userItem = userItemData.data();
db.collection("projects").doc(userItem.project[0]).get()
.then(projectData => {
db.collection("sales").where("project", "==", projectData.id).get()
.then((sales) => {
let i = 0;
sales.forEach((sale) => {
sale.data().customer.get()
.then(customer => {
let salesData = {
key: sale.id,
name: customer.data().name,
sold: sale.data().sold,
date: new Date(sale.data().time.toDate()).getDate() + "." + new Date(sale.data().time.toDate()).getMonth() + "." + + new Date(sale.data().time.toDate()).getFullYear(),
};
salesDataList.push(salesData)
if (sales.size -1 === i++) {
setSalesList(salesDataList);
setIsLoading(false);
}
})
});
});
});
});
}
useEffect(() => {
setupProject();
}, []);
return(
<>
<NavBar />
<div className="header header-fixed header-logo-center">
<a className="header-title">Verkäufe</a>
<i className="fas fa-user"/>
<i className="fas fa-plus"/>
</div>
{isLoading ? (
<div className="page-content header-clear-medium">
<div className="content mt-0" style={{
marginBottom: 16,
marginLeft: 16,
marginRight: 16
}}>
<p>Lädt...</p>
</div>
</div>
) : (
<div className="page-content header-clear-medium">
<div className="card card-style" style={{
marginBottom: "16px"
}}>
<div className="content mb-0">
<div className="input-style input-style-always-active has-borders no-icon">
<select id="dropdownStatus" style={{
color: "darkslategray"
}}>
<option value="all">Alle Status</option>
</select>
<span><i className="fa fa-chevron-down"/></span>
<i className="fa fa-check disabled valid color-green-dark"/>
<em/>
</div>
<div className="input-style input-style-always-active has-borders no-icon">
<select id="dropdownCustomer" style={{
color: "darkslategray"
}}>
<option value="all">Alle Käufer</option>
</select>
<span><i className="fa fa-chevron-down"/></span>
<i className="fa fa-check disabled valid color-green-dark"/>
<em/>
</div>
</div>
</div>
{salesList.length > 0 && console.log(salesList.length)}
{salesList.map(saleItem => (
<a key={saleItem.key} className="card card-style mb-3 filterDiv" style={{display: "block"}}>
<div className="content">
<h3>{saleItem.name} - {saleItem.sold} Eier
<span data-menu="menu-contact-2" style={{float: "right"}}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-red-dark">
<i className="fas fa-times"/>
</span>
</span>
<span style={{float: "right"}}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-blue-dark">
<i className="fas fa-pen"/>
</span>
</span>
</h3>
<div className="row mb-n2 color-theme">
<div className="col font-10 text-start">
<span className="badge bg-green-dark color-white font-10 mt-2">Bezahlt</span>
</div>
<div className="col font-10 text-end opacity-30">
<i className="fa fa-calendar pe-2"/>12.12.2020 <span className="copyright-year"/>
</div>
</div>
</div>
</a>
))}
</div>
)}
</>
);
}
export default Sales;```

Related

Mapping over products and getting an "Objects are not valid as a React child" error

My React.js code is getting this error:
Objects are not valid as a React child (found: object with keys {rate, count}). If you meant to render a collection of children, use an array instead.
import logo from './logo.png';
import './App.css';
import React, { useState, useEffect } from "react";
import axios from "axios";
const idealoBackendUrl = "https://fakestoreapi.com/products"
function App() {
const render_products = (Products) => {
console.log('.............................')
console.log(Products)
console.log('lllllllllllllllllllllllllllll')
console.log(Products[0])
console.log(typeof(Products))
const result = Object.values(Products[0]);
console.log(result);
console.log('result typeee')
console.log(typeof(result));
console.log('................................')
console.log(itemData)
console.log(typeof(itemData))
return <div className='category-section fixed'>
<h2 className="text-3xl font-extrabold tracking-tight text-gray-600 category-title">Products</h2>
<div className="m-6 p-3 mt-10 ml-0 grid grid-cols-1 gap-y-10 gap-x-6 sm:grid-cols-2 lg:grid-cols-6 xl:gap-x-10" style={{ maxHeight: '800px', overflowY: 'scroll' }}>
{/* Loop Products */}
{Products[0].map(product => (
<div className="group relative shadow-lg" >
<div className=" min-h-80 bg-gray-200 aspect-w-1 aspect-h-1 rounded-md overflow-hidden group-hover:opacity-75 lg:h-60 lg:aspect-none">
<img
alt="Product Image"
src={logo}
className="w-full h-full object-center object-cover lg:w-full lg:h-full"
/>
</div>
<div className="flex justify-between p-3">
<div>
<h3 className="text-sm text-gray-700">
<a href={product.href}>
<span aria-hidden="true" className="absolute inset-0" />
<span style={{ fontSize: '16px', fontWeight: '600' }}>{product.item_name}</span>
</a>
<p>Tag -</p>
</h3>
<p className="mt-1 text-sm text-gray-500">Rating: {product.rating}</p>
</div>
<p className="text-sm font-medium text-green-600">${product.current_price}</p>
</div>
</div>
))}
</div>
</div>
}
const [itemData, setItemData] = useState(null);
const [error, setError] = React.useState(null);
useEffect(() => {
getItemDataWithAxios().then(r => console.log(r));
}, []);
const getItemDataWithAxios = async () => {
const response = await axios.get(idealoBackendUrl);
console.log('print response data')
console.log(response.data);
setItemData(response.data);
};
if (error) return `Error: ${error.message}`;
if (!itemData) return <center style={{ marginTop: '200px' }}> <img src="https://icons8.com/preloaders/preloaders/1474/Walk.gif" style={{ width: '70px' }} /> </center>;
return (
<div className="flex fixed flex-row">
<div className="h-screen bg-slate-800 p-3 xl:basis-1/5" style={{ minWidth: '65%' }}>
<img className="w-full" src={logo} alt="Sunset in the mountains" />
<div className="px-6 py-4">
<h1 className="text-3xl mb-2 font-bold text-white"> Idealo product catalog </h1>
<p className="text-gray-700 text-white">
by - <b style={{ color: 'orange' }}>Sithija</b>
</p>
</div>
</div>
<div className="ml-5 p-10 xl:basis-4/5">
{render_products([itemData])}
</div>
</div>
// </>
);
}
export default App;
I have the above piece of code and I keep getting the above-mentioned error, but I cannot find the root cause.
I noticed that when calling render_products = (Products), Products is a single object array where it should be a 20 object array. I have tried Products[0] also with no success.
Can anyone see what's wrong here?
Issue is in the question title, you are trying to display {product.rating} in the render_products method. It is not a number but an object of {rate, count} as keys. Please refer the below code.
import React, { useState, useEffect } from "react";
import axios from "axios";
const idealoBackendUrl = "https://fakestoreapi.com/products"
function App() {
const render_products = (Products) => {
return <div className='category-section fixed'>
<h2 className="text-3xl font-extrabold tracking-tight text-gray-600 category-title">Products</h2>
<div className="m-6 p-3 mt-10 ml-0 grid grid-cols-1 gap-y-10 gap-x-6 sm:grid-cols-2 lg:grid-cols-6 xl:gap-x-10" style={{ maxHeight: '800px', overflowY: 'scroll' }}>
{/* Loop Products */}
{Products.map(product => (
<div className="group relative shadow-lg" >
<div className=" min-h-80 bg-gray-200 aspect-w-1 aspect-h-1 rounded-md overflow-hidden group-hover:opacity-75 lg:h-60 lg:aspect-none">
<img
alt="Product Image"
src=""
className="w-full h-full object-center object-cover lg:w-full lg:h-full"
/>
</div>
<div className="flex justify-between p-3">
<div>
<h3 className="text-sm text-gray-700">
<a href={product.href}>
<span aria-hidden="true" className="absolute inset-0" />
<span style={{ fontSize: '16px', fontWeight: '600' }}>{product.item_name}</span>
</a>
<p>Tag -</p>
</h3>
{/* Here was the issue */}
<p className="mt-1 text-sm text-gray-500">Rating: {product.rating.rate}</p>
</div>
<p className="text-sm font-medium text-green-600">${product.current_price}</p>
</div>
</div>
))}
</div>
</div>
}
const [itemData, setItemData] = useState(null);
const [error, setError] = React.useState(null);
useEffect(() => {
getItemDataWithAxios().then(r => console.log(r));
}, []);
const getItemDataWithAxios = async () => {
const response = await axios.get(idealoBackendUrl);
console.log('print response data')
console.log(response.data);
setItemData(response.data);
};
if (error) return `Error: ${error.message}`;
if (!itemData) return <center style={{ marginTop: '200px' }}> <img src="https://icons8.com/preloaders/preloaders/1474/Walk.gif" style={{ width: '70px' }} /> </center>;
return (
<div className="flex fixed flex-row">
<div className="h-screen bg-slate-800 p-3 xl:basis-1/5" style={{ minWidth: '65%' }}>
<img className="w-full" src="" alt="Sunset in the mountains" />
<div className="px-6 py-4">
<h1 className="text-3xl mb-2 font-bold text-white"> Idealo product catalog </h1>
<p className="text-gray-700 text-white">
by - <b style={{ color: 'orange' }}>Sithija</b>
</p>
</div>
</div>
<div className="ml-5 p-10 xl:basis-4/5">
{render_products(itemData)}
</div>
</div>
// </>
);
}
export default App;
Feel free to edit the code to include your logo component and other icons, I removed them since I don't have the copy of those items.
Try this:
...
{Products.map(product => (
...

Uncaught TypeError: state.productDetails is not a function

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. :)

How to add active class on div on link click inside of div

I want to add active class to the parent element of the div, but the problem is this code is adding on double click not on single click, how to fix this.
The below code is for the sidebar which I want to show on my website, everything is fine but the problem is the handleActiveClass function is not working on single click.
import React from 'react';
import { Link } from 'react-router-dom';
import './Sidebar.css';
const Sidebar = ({ sidebarOpen, closeSidebar, handleLogout }) => {
let logoUrl = JSON.parse(localStorage.getItem('app_icon'));
const handleActiveClass = (e) => {
e.target.parentElement.classList.toggle('active_menu_link');
};
return (
<div id='sidebar' className={sidebarOpen ? 'sidebar-responsive' : ''}>
<div className='sidebar_title'>
<div className='sidebar_img'>
<img src={`https://stucharge.bakersbrisk.com${logoUrl}`} alt='logo' />
<h1>Admin Panel</h1>
</div>
<i className='fa fa-times' id='sidebaricon' onClick={closeSidebar}></i>
</div>
<div className='sidebar_menu'>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-home'></i>
<Link to='/home'>Dashboard</Link>
</div>
<h2>MNG</h2>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-user-circle'></i>
<Link to='/profile'>Profile </Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-book'></i>
<Link to='/subjects'>Subjects </Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-graduation-cap'></i>
<Link to='/courses'>Courses</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-book-open'></i>
<Link to='/notes'>Notes</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-chalkboard-teacher'></i>
<Link to='/class'>Online Class</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-handshake-o'></i>
<Link to='/contact'>Contact Developer</Link>
</div>
<h2>LEAVE</h2>
<div className='sidebar_logout'>
<i className='fa fa-power-off'></i>
<Link to='/' onClick={handleLogout}>
Log out
</Link>
</div>
<div
className='dev'
style={{ position: 'absolute', bottom: '20px', left: '8px' }}
>
<h3 style={{ color: '#51c4d3' }}>
Developed by{' '}
<i
className='far fa-thumbs-up'
style={{ fontSize: '1.6rem', marginLeft: '4px' }}
></i>
</h3>
<h2 style={{ color: '#b0efeb' }}>Codeven Solution</h2>
</div>
</div>
</div>
);
};
export default Sidebar;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
This code might not run here, but you can understand it as i have pasted the whole code.

dispatchConfig: {…}, _targetInst: FiberNode, _dispatchInstances ReactJS error

Hello ,
I was trying to code basket functions on react(onAdd func). But I encountered such a problem. Could you please tell me why? i have no idea about it .
You can see problem from here
I tried to add the add-to-cart function to my button, but I am facing such a problem, could you please tell me why?
import { Row, Col, Form, Button, Label, Input } from "reactstrap";
import Link from "next/link";
import items from "../data/products-cart.json";
import SelectBox from "./SelectBox";
import Stars from "./Stars";
import { useState } from "react";
export default function DetailMain({product}) {
const[CartItems,setCartItems]=useState(items);
console.log(CartItems);
const onAdd=(product)=>{
const exists=CartItems.find(x=>x.id === product.id);
if(exists){
setCartItems(
CartItems.map((x)=>
x.id===product.id ?{...exists,items: exists.items+1}:x
)
);
} else{
setCartItems([...CartItems,{...product,items:1}]);
}
};
console.log(product);
return (
<>
<h1 className="mb-4">{product.name}</h1>
<div className="d-flex flex-column flex-sm-row align-items-sm-center justify-content-sm-between mb-4">
<ul className="list-inline mb-2 mb-sm-0">
<li className="list-inline-item h4 font-weight-light mb-0">
${product.price.toFixed(2)}
</li>
<li className="list-inline-item text-muted font-weight-light">
<del>${product.priceBefore.toFixed(2)}</del>
</li>
</ul>
<div className="d-flex align-items-center">
<Stars
stars={4}
secondColor="gray-300"
starClass="mr-1"
className="mr-2"
/>
<span className="text-muted text-uppercase text-sm mt-1">
{product.reviewscount} reviews
</span>
</div>
</div>
<p className="mb-4 text-muted">{product.description.short}</p>
<Form>
<Row>
<Col sm="6" lg="12" xl="6" className="detail-option mb-4">
<h6 className="detail-option-heading">
Size <span>(required)</span>
</h6>
<SelectBox options={product.sizes} />
</Col>
<Col sm="6" lg="12" xl="6" className="detail-option mb-4">
<h6 className="detail-option-heading">
Type <span>(required)</span>
</h6>
{product.types.map((type) => (
<Label
key={type.value}
className="btn btn-sm btn-outline-secondary detail-option-btn-label mr-2"
tag="label"
for={type.id}
>
{" "}
{type.label}
<Input
className="input-invisible"
type="radio"
name="material"
value={type.value}
id={type.id}
required
/>
</Label>
))}
</Col>
<Col xs="12" lg="6" className="detail-option mb-5">
<label className="detail-option-heading font-weight-bold">
Items <span>(required)</span>
</label>
<input
className="form-control detail-quantity"
name="items"
type="number"
defaultValue={1}
/>
</Col>
</Row>
<ul className="list-inline mb-5">
<li className="list-inline-item">
<Button onClick={onAdd} color="dark" size="lg" className="mb-1" type="submit">
<i className="fa fa-shopping-cart mr-2" />
Add to Cart
</Button>
</li>
<li className="list-inline-item">
<Button color="outline-secondary" className="mb-1" href="#">
<i className="far fa-heart mr-2" />
Add to wishlist
</Button>
</li>
</ul>
<ul className="list-unstyled">
<li>
<strong>Category: </strong>
<a className="text-muted" href="#">
{product.category}
</a>
</li>
<li>
<strong>Tags: </strong>
{product.tags.map((tag, index) => (
<React.Fragment key={tag.name}>
<Link href={tag.link}>
<a className="text-muted">{tag.name}</a>
</Link>
{index < product.tags.length - 1 ? ",\u00A0" : ""}
</React.Fragment>
))}
</li>
</ul>
</Form>
</>
);
}
Your data should be in the same format as the data you rendered before.

Preventing duplicate objects being added to firebase back end

I have a question regarding preventing duplicates from being added to
cart while using firebase as back-end.
It should be straight forward but for some reason, nothing I try is working.
const { products } = this.props;
return (
<div>
{products === undefined ? (
<p>Loading......</p>
) : (
products.map(val => {
return (
<div key={val.id} className="row">
<div className="col-sm-6">
<div className="card-body">
<img src={val.url} className="img-fluid" alt="Responsive" />
<h5 className="card-title">{val.name}</h5>
<h6 className="card-subtitle mb-2 text-muted">
{val.price}
</h6>
<button
className=" "
style={{
float: "right",
marginBottom: "1px",
width: "100%"
}}
onClick={() => this.submit(val)}
>
<i className="fas fa-cart-plus" />
</button>
</div>
</div>
</div>
);
})
)}
</div>
);

Categories