Inverse map and use if inside a map method - javascript

In the categories.map((category) => () I need to inverse the elements of the categories.map and check for category.isFeatured befor making a link but it doesn't let me make an if statement.
const Header = () => {
const [categories, setCategories] = useState([])
useEffect(() => {
getCategories().then((newCategories) => setCategories(newCategories))
}, [])
return (
<div className="container mx-auto mb-8 px-10">
<div className="inline-block w-full border-b border-blue-400 py-8">
<div className="block md:float-left">
<span className="cursor-pointer text-4xl font-bold text-white">
<Link href={'/'}>CRBStuffReviews</Link>
</span>
</div>
<div className="hidden md:float-left md:contents">
{categories.map((category) => (
<Link key={category.slug} href={`/category/${category.slug}`}>
<span className="mt-2 ml-4 cursor-pointer align-middle font-semibold text-white md:float-right">
{category.name}
{console.log(category.name)}
</span>
</Link>
))}
</div>
</div>
</div>
)
}

Bravo is right on the Array.reverse in the comments.
You also need to add {} in the .map, check category.isFeatured, and remove any nulls (or you'll get blank rows).
For example the following will reverse the order, return the link if category.isFeatured, else return null. Finally it will remove all nulls with filter(Boolean) - a nifty trick:
import React, { useState, useEffect } from "react";
const Header = () => {
const [categories, setCategories] = useState([]);
useEffect(() => {
getCategories().then((newCategories) => setCategories(newCategories));
}, []);
return (
<div className="container mx-auto mb-8 px-10">
<div className="inline-block w-full border-b border-blue-400 py-8">
<div className="block md:float-left">
<span className="cursor-pointer text-4xl font-bold text-white">
<Link href={"/"}>CRBStuffReviews</Link>
</span>
</div>
<div className="hidden md:float-left md:contents">
{categories
.reverse()
.map((category) => {
return category.isFeatured ? (
<Link key={category.slug} href={`/category/${category.slug}`}>
<span className="mt-2 ml-4 cursor-pointer align-middle font-semibold text-white md:float-right">
{category.name}
{console.log(category.name)}
</span>
</Link>
) : null;
})
.filter(Boolean)}
</div>
</div>
</div>
);
};

In the map callback function, you need to use curly bracket
{}
Inside the curly bracket you can use the IF statement
So, Your code will looks like this
const Header = () => {
const [categories, setCategories] = useState([])
useEffect(() => {
getCategories().then((newCategories) => setCategories(newCategories))
}, [])
return (
<div className="container mx-auto mb-8 px-10">
<div className="inline-block w-full border-b border-blue-400 py-8">
<div className="block md:float-left">
<span className="cursor-pointer text-4xl font-bold text-white">
<Link href={'/'}>CRBStuffReviews</Link>
</span>
</div>
<div className="hidden md:float-left md:contents">
{categories.map((category) => {
if(category.isFeatured){
return(
<Link key={category.slug} href={`/category/${category.slug}`}>
<span className="mt-2 ml-4 cursor-pointer align-middle font-semibold text-white md:float-right">
{category.name}
{console.log(category.name)}
</span>
</Link>
)}})}
</div>
</div>
</div>
)
}

Try it:
<div className="hidden md:float-left md:contents">
{mrGlobalRequest?.map((category) => {
if (category.isFeatured)
return (
<div key={category.slug} href={`/category/${category.slug}`}>
<span className="mt-2 ml-4 cursor-pointer align-middle font-semibold text-white md:float-right">
{category.name}
{console.log(category.name)}
</span>
</div>
);
})}
</div>

Related

Make Submenu on sidebar component Nextjs

So it to loop and subMenu on sidebar component, but instead of the subMenu showUp under the parents menu, it showUp on the Right side of the parents menu as pic below:
here is my code on how i try to loop the subMenu and The parents item to the react component:
return (
<div className=" my-4 border-gray-100 pb-4">
{items.map(({ icon: Icon, iconArrow: IconArrow, ...item }, index) => {
if (item.subMenu) {
return (
<div>
<Link href={item.link}>
<a
onClick={(e) => onMouseClick(e, item.link)}
className="flex mb-2 justify-start items-center gap-4 pl-5 hover:bg-gray-900 p-2 rounded-md group cursor-pointer hover:shadow-lg m-auto"
>
<Icon className="text-2xl text-white group-hover:text-red" />
<h3 className="text-base text-white group-hover:text-red font-semibold ">
{item.label}
</h3>
{item.subMenu && dropdown ? (
<>
<IconArrow className="pl-0 text-2xl text-white group-hover:text-red" />
</>
) : (
<></>
)}{" "}
{item.subMenu && dropdown ? (
<div>
{item.subMenu.map((subitem, index) => {
return <>makan</>;
})}
</div>
) : (
<></>
)}
</a>
</Link>
</div>
);
} else {
return (
// eslint-disable-next-line react/jsx-key
<div>
<Link href={item.link}>
<a
onClick={(e) => onMouseClick(e, item.link)}
className="flex mb-2 justify-start items-center gap-4 pl-5 hover:bg-gray-900 p-2 rounded-md group cursor-pointer hover:shadow-lg m-auto"
>
<Icon className="text-2xl text-white group-hover:text-red" />
<h3 className="text-base text-white group-hover:text-red font-semibold ">
{item.label}
</h3>
</a>
</Link>
</div>
);
}
})}
</div>
);
};
Can Some one tell me where did i do wrong here, here is where i call the sidebar component into the sidebar:
return (
<div className="h-full px-4 pt-8 bg-yellow flex flex-col peer-focus:left-0 peer:transition ease-out delay-150 duration-200">
<div className="flex flex-col justify-start item-center mb-4">
<Image src={Logo_Nabati} width={123} height={75} alt="logo Nabati" />
</div>
<Sidebarcomponent items={menuItems} />;
</div>
);
try this:
return (
<div className=" my-4 border-gray-100 pb-4 relative">
{items.map(({ icon: Icon, iconArrow: IconArrow, ...item }, index) => {
if (item.subMenu) {
return (
<div className="absolute top-full left-0">...</div>
);
} else {...})}
</div>
);
};
I assume you want to display the submenu under the "Master Data"? Put the component under it. Then in the anchor tag you have a flex. Add flex-col to change the direction of flex, top-bottom.

why does react button disabled not working while using tailwind css along

import React, { useState } from "react";
import facebook from "../UI/icons/facebook.png";
import Button from "../UI/Button/Button";
import Card from "../UI/Card/Card";
import twitter from "../UI/icons/twitter.png";
import instagram from "../UI/icons/instagram.png";
const Login = () => {
const [enteredEmail, setEnteredEmail] = useState("");
const [emailIsValid, setEmailIsValid] = useState("");
const [enteredPassword, setEnteredPassword] = useState("");
const [passwordIsValid, setPasswordIsValid] = useState("");
const [formIsValid, setFormIsValid] = useState("");
const emailChangeHandler = (event) => {
setEnteredEmail(event.target.value);
setFormIsValid(
event.target.value.includes("#") && enteredPassword.trim().length > 6
);
};
const passwordChangeHandler = (event) => {
setEnteredPassword(event.target.value);
setFormIsValid(
event.target.value.trim().length > 6 && enteredEmail.includes("#")
);
};
const validateEmailHandler = () => {
setEmailIsValid(enteredEmail.includes("#"));
};
const validatePasswordHandler = () => {
setPasswordIsValid(enteredPassword.trim().length > 6);
};
const submitHandler = (event) => {
event.preventDefault();
console.log(enteredEmail);
console.log(enteredPassword);
};
return (
<Card className="bg-slate-100 border-1 rounded-xl shadow-xl w-[30vw] m-auto mt-20 mb-20">
<div className="flex justify-center text-2xl font-bold pt-4">Login</div>
<div className="flex justify-center px-0 py-5">
<form onSubmit={submitHandler}>
<div>
<label htmlFor="email" className="text-lg font-bold">
E-mail
</label>
<div>
<input
value={enteredEmail}
type="email"
id="email"
placeholder="Type your email"
className={
emailIsValid === false
? "bg-red-200 border-b-[2px] border-red-600 text-white text-lg px-1 rounded shadow-md h-10 w-[19rem] outline-none"
: "border-b-[2px] text-lg px-1 rounded shadow-md border-gray-400 h-10 w-[19rem] outline-none"
}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
</div>
</div>
<div className="mt-4">
<label className="text-lg font-bold" htmlFor="password">
Password
</label>
<div>
<input
value={enteredPassword}
type="password"
id="password"
placeholder="Type your password"
className={
passwordIsValid === false
? "bg-red-200 border-b-[2px] border-red-600 text-white text-lg px-1 rounded shadow-md h-10 w-[19rem] outline-none"
: "border-b-[2px] text-lg px-1 rounded shadow-md border-gray-400 h-10 w-[19rem] outline-none"
}
onChange={passwordChangeHandler}
onBlur={validatePasswordHandler}
/>
</div>
<div className="flex justify-end">Forget password</div>
</div>
<div className="flex justify-center">
<Button
className="mt-4 border-gray-400 rounded-xl px-32 py-2 cursor-pointer shadow-md bg-slate-400 hover:bg-slate-600 hover:text-white"
type="submit"
disabled={!formIsValid}
>
LOGIN
</Button>
</div>
<div className="flex justify-center mt-4">Or Sign Up Using</div>
<div className="flex justify-center mt-2 ">
<div className="mx-1">
<img src={instagram} alt="facebook" width="30" />
</div>
<div className="mx-1">
<img src={twitter} alt="facebook" width="30" />
</div>
<div className="mx-1">
<img src={facebook} alt="facebook" width="30" />
</div>
</div>
<div className="flex justify-center mt-[9rem]">Or Sign Up Using</div>
<div className="flex justify-center">SIGN UP</div>
</form>
</div>
</Card>
);
};
export default Login;
this is button code where i've error
<Button
className="mt-4 border-gray-400 rounded-xl px-32 py-2 cursor-pointer shadow-md bg-slate-400 hover:bg-slate-600 hover:text-white"
type="submit"
disabled={!formIsValid}
>
LOGIN
</Button>
image
this is my code's output and i want to make this LOGIN button disable while validating fields but it don't work while i am using className that contain tailwind code..
i also have a piic and code where disable works.
<Button
//className="mt-4 border-gray-400 rounded-xl px-32 py-2 cursor-
//pointer shadow-md bg-
//slate-400 hover:bg-slate-600 hover:text-white"
type="submit"
disabled={!formIsValid}
>
LOGIN
</Button>
image
now disable is working as i have commented out className attribute.
It is working, the button is not clickable, but the style isn't changing because you need to choose what the disabled state style looks like using disabled: in your class (You need Tailwind version >= v1.1.0)
Little example of a button
<Button
class="bg-green-300 disabled:bg-gray-400"
disabled={!formIsValid}
>
Click me
</Button>
You also need to enable the disabled variant in your tailwind.config.js with something like this
module.exports = {
variants: {
extend: {
backgroundColor: ["disabled"],
textColor: ["disabled"]
},
}
I am not a react dev so maybe someone can confirm this, but you should also change your useState("") to useState(true) where it is appropriate, basically all your IsValid variables, since they should be Booleans and not Strings
I was struggling with disabling an input field and decided to use a workaround using only the classes with a helper function:
export function classNames(...classes) {
return classes.filter(Boolean).join(' ');
}
which can be used like this
import { classNames } from 'wherever/you/store/helpers';
<Button
className={classNames(
'font-semibold',
formIsValid
? 'bg-green-300 text-green-900'
: 'bg-gray-300 text-gray-600 cursor-not-allowed'
)}
disabled={!formIsValid}
>
Click me
</Button>
This is useful in general for dynamically applying styles, since Tailwind CSS 3 does not support dynamic class names.

Why react HeroIcons does not take color?

I am trying to use a hero icon from heroicons, in a react project.
import React, { useState } from 'react';
import { MenuIcon, XIcon } from '#heroicons/react/solid';
export const Sidebar = () => {
const [showSidebar, setShowSidebar] = useState<boolean>(false);
return (
<div
className="flex justify-between items-center
p-2
m-auto"
>
{showSidebar ? (
<div>
<XIcon
onClick={() => setShowSidebar(!showSidebar)}
className="h-5 w-5 text-white cursor-pointer"
/>
</div>
) : (
<div>
<MenuIcon onClick={() => setShowSidebar(!showSidebar)} className="h-5 w-5 text-white" />
</div>
)}
<div
className={`top-0 left-0 w-[45vw] bg-menubar p-10 pl-20 text-white fixed h-full z-40 ${
showSidebar ? 'translate-x-0 ' : 'translate-y-full'
}`}
>
<h2 className="mt-5 text-2xl font-semibold text-white">I am a sidebar</h2>
</div>
</div>
);
};
I am conditionally displaying a sidebar.
XIcon is hwoing in my dom.
But it does not take any color.
how about trying with fill-white instead of text-white e.g:
<XIcon
onClick={() => setShowSidebar(!showSidebar)}
className="h-5 w-5 fill-white cursor-pointer"
/>

Next.js keeps throwing error params is undefined

I have successfully connected my custom server using Node.js and Express.js with Next.js. I'm trying to fetch a car by its id whenever I click it among other cars, so I can have that particular car only. But I keep getting an error saying params is undefined even though I get the id at the back of my link whenever I click on the single car in the browser. I've tried fetching the data using thunder client and everything works fine. I believe something is wrong with my frontend logic.
This is where I'm trying to fetch the data with the id
<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>
import Layout from "#/components/Layout";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import Authorization from "#/HOC/Authorization";
import axios from "axios";
const Car = () => {
const [data, setData] = useState("");
const oneCar = async (params) => {
const { id } = params;
const res = await axios.get(`http://localhost:5000/one-car/${id}`);
setData(res.data);
if (res.status !== 200) {
console.log(res.status);
}
};
useEffect(() => {
oneCar();
}, []);
return (
<Layout>
{data && (
<div className="flex flex-col w-11/12 mx-auto mt-8 justify-center bg-blue-200 rounded-lg shadow">
<div className="flex w-full justify-center mt-6 px-4 mx-auto box-shadow-lg h-2/4 relative">
<Image
src="/assets/images/d17.jpg"
alt="shopping image"
className="mx-auto flex rounded-lg inset-0 w-full h-2/4 object-cover"
width={1000}
height={500}
/>
</div>
<form className="flex-auto p-6">
<div className="flex flex-wrap">
<h1 className="flex-auto text-xl font-semibold text-gray-800">
{data.carName}
</h1>
<div className="text-xl font-semibold text-gray-700 ">
{data.carPrice}
</div>
<div className="w-full flex-none text-sm font-medium text-gray-500 mt-2">
In stock
</div>
</div>
<div className="flex items-baseline mt-4 mb-6 text-gray-800 ">
<Link
href="#"
className="ml-auto hidden md:block text-sm text-gray-500 underline"
>
Size Guide
</Link>
</div>
<div className="flex mb-4 text-sm font-medium">
<button
type="button"
className="py-2 px-4 bg-blue-700 hover:bg-blue-800 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full sm:w-1/4 transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 mx-auto rounded-lg "
>
Buy now
</button>
</div>
<p className="text-sm text-gray-500 text-center ">
Free shipping on all continental US orders.
</p>
</form>
</div>
)}
</Layout>
);
};
export default Authorization(Car);
This is where I fetch all cars and makes the id a parameter to the link address
<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>
import Image from "next/image";
import Layout from "#/components/Layout";
import Pagination from "#/components/Pagination";
import { GiBinoculars } from "react-icons/gi";
import { useGetAllCarsQuery } from "#/store/ReduxStore/getAllCarsApi";
import Link from "next/link";
const Market = () => {
//I use RTK Query to fetch the data, and It was successfully fetched
const { data, isLoading, error } = useGetAllCarsQuery();
return (
<Layout>
<div className="2xl:container 2xl:mx-auto">
<div className=" py-3 lg:px-20 md:px-6 px-4">
<div className=" flex justify-center mt-3 items-center">
<div className=" flex space-x-3 justify-center items-center">
<span className="bg-blue-800 px-4 py-2 rounded-md text-2xl text-white">
<GiBinoculars />
</span>
<input
type="search"
className="border-b-2 w-9/12 border-gray-700 -mb-3 leading-5 text-lg p-2 focus:outline-none"
placeholder="Search for cars here..."
/>
</div>
</div>
<hr className=" w-full bg-gray-200 my-6" />
<div className=" grid lg:grid-cols-4 sm:grid-cols-2 grid-cols-1 lg:gap-y-12 lg:gap-x-8 sm:gap-y-10 sm:gap-x-6 gap-y-6 lg:mt-12 mt-10">
{data?.map((cars, i) => (
<Link
key={i}
href="/[id]"
as={`${cars._id}`}
//I insert the id here
className="relative"
passHref
>
<div>
<div className=" relative group">
<div className="caroverlay"></div>
<Image
width={600}
height={400}
className="rounded-md w-full"
src="/assets/images/d17.jpg"
alt="A girl Posing Img"
/>
<div className=" absolute bottom-0 p-8 w-full opacity-0 group-hover:opacity-100 z-20">
<button className="text-base font-bold leading-4 text-gray-600 hover:bg-gray-300 hover:text-gray-700 bg-white py-3 w-full">
Add to your garage
</button>
<button className=" bg-transparent text-base font-bold leading-4 border-2 hover:bg-gray-300 hover:text-gray-700 border-white py-3 w-full mt-2 text-white">
View Car
</button>
</div>
</div>
<p className=" text-xl leading-5 text-gray-600 md:mt-6 mt-4">
{cars.carName}
</p>
<p className=" font-semibold text-xl leading-5 text-gray-800 mt-4">
<span>$</span> {cars.carPrice}
</p>
</div>
</Link>
))}
</div>
{/* _______________________________________________________ */}
<Pagination />
{/* _______________________________________________________ */}
</div>
</div>
</Layout>
);
};
export default Market;
Here is my backend logic
<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>
const router = require("express").Router();
const auth = require("../../middleware/auth");
const Car = require("../../Model/CarSchema");
router.get("/onecar/:id", auth, async (req, res) => {
try {
const car = await Car.findById(req.params.id);
res.status(200).json(car);
} catch (err) {
res.status(500).json({ msg: "Server Error" });
}
});
module.exports = router;
To access id in nextjs. I imported useRouter from next/router. Then I const router = useRouter(). Then const {id} = router.query

useState being set to false but ternary operator not working

I have a simple state let [isOpen, setIsOpen] = useState(false);
It doesn't when it gets back set to false it the ternary operator doesn't seem to be doing anything.
export default function ShowContact(props) {
let [isOpen, setIsOpen] = useState(false);
...
function closeButtons() {
setIsOpen(false);
console.log(isOpen);
}
I have the following
{!isOpen ? <span>TRUE</span> : <span>FALSE</span>}
{!isOpen ? (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={closeButtons}
>
<span className="text-center tracking-wide">delete</span>
</button>
</div>
</div>
) : (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-green-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-green-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={deleteContact}
>
<span className="text-center tracking-wide">yes delete</span>
</button>
</div>
</div>
)}
the {isOpen ? <span>TRUE</span> : <span>FALSE</span>} is simple to test that isOpen is being set to false. Which is does as I have checked the console.
Still though the ternary isn't changing. This is very annoying as it was working earlier and something has changed I am not sure if this is an effect from other components, but I can not see why?
But I know the buttons are working as the deleteContact function is working and the isOpen is getting set to false
I am complete miffed about this, any suggestions would be welcome.
import { useEffect, useState } from 'react';
export default function ShowContact(props) {
let [isOpen, setIsOpen] = useState(false);
let [contact, setContact] = useState({});
// delete contact from api then reloads the page
function deleteContact() {
fetch(`http://localhost:8000/delete-contact/${props.contactId}`, {
method: 'DELETE',
}).catch((err) => console.log(err));
setIsOpen(false);
window.location.reload(true);
}
// get contact from api by contact id
useEffect(() => {
async function fetchContact() {
await fetch(`http://localhost:8000/get-contact/${props.contactId}`)
.then((response) => response.json())
.then((data) => {
setContact(data);
})
.catch((err) => console.log(err));
}
if (props.open) {
fetchContact();
}
}, []);
function closeButtons() {
setIsOpen(false);
console.log(isOpen);
}
function openButtons() {
setIsOpen(true);
console.log(isOpen);
}
return (
<div className="bg-gray-100 p-4">
<div>
{/* <div className="mx-auto my-4 block w-fit rounded-full bg-gray-300 p-6 ">
...
</div> */}
<div className="flex flex-col text-center">
<span className="font-bold">
{contact.first_name} {contact.last_name}
</span>
<span className="text-sm text-gray-400">{contact.company}</span>
</div>
{contact.telephone !== '' || contact.telephone === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">telephone</span>
<a
href={`tel:${contact.telephone}`}
className="text-sm text-blue-500"
>
{contact.telephone}
</a>
</div>
) : null}
{contact.email !== '' || contact.email === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">email</span>
<a
href={`mailto:${contact.email}`}
className="text-sm text-blue-500"
>
{contact.email}
</a>
</div>
) : null}
{contact.address !== '' || contact.address === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">address</span>
<span className="text-sm text-blue-500">{contact.address}</span>
</div>
) : null}
{contact.notes !== '' || contact.notes === 'NULL' ? (
<div className="my-4 flex flex-col rounded-md bg-white p-4 text-left">
<span className="text-sm font-medium">notes</span>
<span className="text-sm">{contact.notes}</span>
</div>
) : null}
</div>
{!isOpen ? <span>TRUE</span> : <span>FALSE</span>}
{!isOpen ? (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-blue-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-blue-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={closeButtons}
>
<span className="text-center tracking-wide">delete</span>
</button>
</div>
</div>
) : (
<div>
<div className="mt-6 flex flex-col">
<button className="mb-1 rounded bg-green-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-green-700">
<span className="text-center">edit</span>
</button>
<button
className="rounded bg-red-500 px-4 py-3 capitalize text-white duration-100 ease-in-out hover:bg-red-700"
onClick={deleteContact}
>
<span className="text-center tracking-wide">yes delete</span>
</button>
</div>
</div>
)}
</div>
);
}
Update with the whole component.
I am checking for isOpen to be false as I want to set some delete buttons, but then confirm the delete once the first set of buttons set isOpen to true

Categories

Resources