Preventing duplicate objects being added to firebase back end - javascript

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>
);

Related

I am found 'subject' is of type 'unknown'. error during the npm start but code is run and working how to resolved it?

Object.entries(APIData).map(([key, subject], i) => {
return (
<div className="id-result" key={i}>
<div id="heading-result">
<h2 key={i} className="heder-result">{subject.title}</h2>
{/* <img id="pdficon" src={pdficon} alt="download pdf" height="20px" /> */}
<Button className="download-button"><PDFReader /></Button>
</div>
<hr className="hr-result" />
{/* <p className="para-result" key={i}>{subject.para}</p> */}
<p dangerouslySetInnerHTML={{ __html: subject.para }}>
</p>
</div>
)
I am facing error on subject that 'subject' is of type 'unknown'.

Using if else condition to show elements on RectJS

I have some menu items I want to show according to user roles. I have 2 user roles form the database (1 for admin and 0 for normal user). But my code always return the menu items for normal user even if its an admin who is logged in.
I am also storing user details in a useContext and calling them on every component
Kindly Help
My Code
import React, { Component } from "react";
import { Link } from "react-router-dom";
import "./Menubar.css";
import { UserContext } from "../../UserContext";
const Menubar = () => {
const user = React.useContext(UserContext);
console.warn(user.role)
return (
<div>
<div className="appBottomMenu">
{user.role === 1 ? (
<Link to="/admin/home" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
) : (
<Link to="/" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
)}
{user.role === 1 ? (
<Link className="item" to="/admin/farmers">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/area" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-marker"></i>
</div>
</Link>
)}
<Link to="/community" className="item">
<div className="col">
<i className="fi fi-rr-browser"></i>
</div>
</Link>
{user.role === 1 ? (
<Link className="item" to="/admin/farms">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/shop" className="item">
<div className="col">
<i className="fi fi-rr-shopping-cart"></i>
</div>
</Link>
)}
<Link to="/profile" className="item">
<div className="col">
<i className="fi fi-rr-user"></i>
</div>
</Link>
</div>
</div>
);}
export default Menubar;
One potential way to force an update on the page on context updates is to utilize the useEffect and useState hooks in conjunction with your useContext. Here is an example, I hope this helps.
For example:
import React, { Component, useEffect, useContext, useState } from "react";
import { Link } from "react-router-dom";
import "./Menubar.css";
import { UserContext } from "../../UserContext";
const Menubar = () => {
const { user } = useContext(UserContext);
const [menuContext, setMenuContext] = useState(user);
const handleSetMenuContext = (updatedMenuContext) => {
setMenuContext(updatedMenuContext);
};
useEffect(() => {
handleSetMenuContext(user);
}, [user]);
return menuContext?.role && (
<div>
<div className="appBottomMenu">
{menuContext.role === 1 ? (
<Link to="/admin/home" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
) : (
<Link to="/" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
)}
{menuContext.role === 1 ? (
<Link className="item" to="/admin/farmers">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/area" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-marker"></i>
</div>
</Link>
)}
<Link to="/community" className="item">
<div className="col">
<i className="fi fi-rr-browser"></i>
</div>
</Link>
{menuContext.role === 1 ? (
<Link className="item" to="/admin/farms">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/shop" className="item">
<div className="col">
<i className="fi fi-rr-shopping-cart"></i>
</div>
</Link>
)}
<Link to="/profile" className="item">
<div className="col">
<i className="fi fi-rr-user"></i>
</div>
</Link>
</div>
</div>
);
}
export default Menubar;

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 => (
...

Stick a Material UI Input when scrolling

I want to make the Material UI Input stick at the top when scrolling, I have a modal an its content is the search input and the results.
I used overflow-y: scroll; in <div className="modal-content"> and used position: sticky; in <OutlinedInput className="SearchInput" /> but then the search and the results scroll together which I don't want it to, I want only the result to scroll.
Then I removed the overflow-y: scroll; from in <div className="modal-content"> and put it in <div className="card" key={post._id}> but then the results went outside the modal borders as in the Image down below
The Code:
return (
<>
<button onClick={toggleModal} className="btn-modal">
<SearchIcon />
</button>
{modal && (
<div className="modal">
<div onClick={toggleModal} className="overlay"></div>
<div className="modal-content">
<div className="searchBar">
<div style={{ padding: 20 }}>
<div font-size="20px" className="searchTry">Search</div>
<OutlinedInput
className="SearchInput"
placeholder='Search...'
onChange={(e) => searchItems(e.target.value)}
endAdornment={
<InputAdornment>
<SearchIcon />
</InputAdornment>
}
/>
<div style={{ marginTop: 20 }}>
{searchInput.length > 0 ? (
filteredResults.map((post) => {
return (
<div className="card" key={post._id}>
<div className="card-content">
<Link to={`/post/${post._id}`} className="link">
<h2 className="results-title">
{post.title}
</h2>
<ol className="card-username">
{post.username}
</ol>
</Link>
</div>
</div>
)
})
) : (
APIData.map((post) => {
return (
<div className="card" key={post._id}>
<div className="card-content">
<Link to={`/post/${post._id}`} className="link">
<h2 className="card-name">
{post.title}
</h2>
<ol className="card-username">
{post.username}
</ol>
</Link>
</div>
</div>
)
})
)}
</div>
</div>
</div>
<button className="close-modal" onClick={toggleModal}>
<CloseIcon />
</button>
</div>
</div>
)}
</>
);

Map doesn't work after setState after fetch

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;```

Categories