skip to Main Content

I have 4 categories anmial , treatment, dailyEssentials and medical-care

On the left side there are 3 cards for treatment, dailyEssentials and medical-care and one drop-down to select by animals.

the product gets updated perfectly for the Animal and the treatment category but dailyEssentials and medical-care are not giving required products as a output instead of that it’s shows all the products.

URL – http://localhost:3000/search/essential/6451eafc000f972917fe38fe

  • 6451eafc000f972917fe38fe is dailyessential category id .

I have a question that the treatment card is very similar to dailyEssentials and medical-care
In my case treatment is working fine then why not dailyEssentials and medical-care.

This is the backend

exports.showAllProducts = catchAsyncError(async (req, res, next) => {
    try {
      // enable search
      const keyword = req.query.keyword
        ? {
            name: {
              $regex: req.query.keyword,
              $options: 'i',
            },
          }
        : {};
  
      // enable filter by animal
      const animalId = req.query.animal;
      const animalFilter = animalId ? { animal: animalId } : {};
  
      // enable filter by treatment
      const treatmentId = req.query.treatment;
      const treatmentFilter = treatmentId ? { treatment: treatmentId } : {};
  
      //enable filter by essentials
      const essentialId = req.query.dailyEssential;
      const essentialFilter = essentialId ? {dailyEssential: essentialId}: {};

      //enable filter by medical care
      const medicalCareId = req.query.medicalCare;
      const medicalCareFilter =  medicalCareId ? {medicalCare: medicalCareId}:{};

      // enable pagination
      const pageSize = 4;
      const page = Number(req.query.pageNumber) || 1;
  
   // construct the filter based on the keyword and any additional filters
   const filter = {
    ...keyword,
    ...animalFilter,
    ...treatmentFilter,
    ...essentialFilter,
    ...medicalCareFilter,
  };
      const count = await Product.find(filter).countDocuments();
      const products = await Product.find(filter)
        .skip(pageSize * (page - 1))
        .limit(pageSize);
  
      res.status(200).json({
        success: true,
        count,
        products,
        page,
        pages: Math.ceil(count / pageSize),
      });
    } catch (error) {
      next(error);
    }
  });

ESSENTIAL_ACTION

import { DAILY_ESSENTIALS_TYPE_LOAD_FAIL, DAILY_ESSENTIALS_TYPE_LOAD_REQUEST, DAILY_ESSENTIALS_TYPE_LOAD_RESET, DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS } from "../../constants/categories/dailyEssentialsConstants";
import axios from 'axios'


export const dailyEssentialsTypeLoadAction = () => async (dispatch) => {
    dispatch({ type: DAILY_ESSENTIALS_TYPE_LOAD_REQUEST });
    try {
        const { data } = await axios.get('/api/v1/essential');
        dispatch({
            type: DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS,
            payload: data
        });
    } catch (error) {
        dispatch({
            type: DAILY_ESSENTIALS_TYPE_LOAD_FAIL,
            payload: error.response.data.error
        });
    }
}

ESSENTIAL REDUCER

import { DAILY_ESSENTIALS_TYPE_LOAD_FAIL, DAILY_ESSENTIALS_TYPE_LOAD_REQUEST, DAILY_ESSENTIALS_TYPE_LOAD_RESET, DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS } from "../../constants/categories/dailyEssentialsConstants";

export const loadDailyEssentialTypeReducer =  (state = {dailyEssentialType:[] },action)=>{
    switch (action.type){
        case DAILY_ESSENTIALS_TYPE_LOAD_REQUEST:
            return { loading : true}
        case DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS:
            return {
                loading: false,
                dailyEssentialType: action.payload.essentialT
            }
        case DAILY_ESSENTIALS_TYPE_LOAD_FAIL:
            return {
                loading: false,
                error: action.payload
            }
        case DAILY_ESSENTIALS_TYPE_LOAD_RESET:
            return {}
        default:
            return state;
    }
}
import React, { useEffect, useState } from 'react';
import './product.css';
import { Box, Card, CardContent, Stack, Typography } from '@mui/material';
import ProductCard from './ProductCard';
import { useDispatch, useSelector } from 'react-redux';
import { getProduct } from '../../actions/productAction';
import { Link, useParams } from 'react-router-dom';
import Pagination from '@mui/material/Pagination';
import Loader from '../layout/Loader/Loader';
import SelectComponent from './SelectComponent';
import { animalTypeLoadAction } from '../../actions/categories/animalTypeAction';
import { treatmentTypeLoadAction } from '../../actions/categories/treatmentTypeAction';
import { dailyEssentialsTypeLoadAction } from '../../actions/categories/dailyEssentialTypeAction';
import { medicalCareTypeLoadAction } from '../../actions/categories/medicalCareTypeAction';


  const dispatch = useDispatch();
  const {error,loading,products,pages} = useSelector(state=>state.products)

  const { keyword,treatment,essential,medical} = useParams()
  const { treatmentType } = useSelector(state => state.treatmentTypeAll)
  const { dailyEssentialType } = useSelector(state => enter image description herestate.dailyEssentialTypeAll)
  const { MedicalCareType } = useSelector(state => state.medicalCareTypeAll)

  const [page, setPage ] = useState(1);
  const [animal, setAnimal ] = useState();

  useEffect(()=>{
    dispatch(getProduct(page,keyword,animal,treatment,essential,medical))
  },[dispatch,page,keyword,animal,treatment,essential,medical])

useEffect(()=>{
  dispatch(animalTypeLoadAction())
  dispatch(treatmentTypeLoadAction())
  dispatch(dailyEssentialsTypeLoadAction())
  dispatch(medicalCareTypeLoadAction())

},[])

  const handleChangeCategory=(e)=>{
      setAnimal(e.target.value)
  }

  return (
    <div>
      {
        loading ? <Loader /> : <>
     <Box sx={{ bgcolor: '#fff', minHeight: '100vh' }}>
        <Stack direction={{ xs: 'column', sm: 'row' }} spacing={{ xs: 1, sm: 2, md: 4 }}>
          <Box sx={{ flex: 2, p: 2 }}>
            <Card sx={{ minWidth: 170, mb: 3, mt: 3, p: 2 }}>
              <Box sx={{ pb: 2 }}>
                <Typography component="h4" sx={{ color: '#217c04', fontWeight: 700, fontFamily: 'Inter' }}>
                  SORT AS PER YOUR PREFERENCE
                </Typography>
              </Box>
              <SelectComponent handleChangeCategory={handleChangeCategory} animal={animal} /> 
            </Card>
                   {/* treatment category  card*/}
          <Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
          <Box sx={{ pb: 2 }}>
              <Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
                        SORT BY TREATMENT
              </Typography>
              {
              treatmentType && treatmentType.map((treatment) => (
                <Link className='link' to={`/search/treatment/${treatment._id.toString()}`} key={treatment._id}>
              <Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
              <CardContent>
              <Typography variant="h6" color="text.primary">
                        {treatment.TreatmentTypeName}
              </Typography>
              </CardContent>
            </Card>
            </Link>
              ))
            }
        </Box>
        </Card>

            {/* daily-Essential-Card */}
            <Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
          <Box sx={{ pb: 2 }}>
              <Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
                        OUR DAILY ESSENTIALS
              </Typography>
              {
              dailyEssentialType && dailyEssentialType.map((essential) => (
                <Link className='link' to={`/search/essential/${essential._id.toString()}`} key={essential._id}>
              <Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
              <CardContent>
              <Typography variant="h6" color="text.primary">
                        {essential.essentialName}
              </Typography>
              </CardContent>
            </Card>
            </Link>
              ))
            }
        </Box>
        </Card>


        {/* medical-care-card */}
        <Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
          <Box sx={{ pb: 2 }}>
              <Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
                        SORT BY Medical
              </Typography>
              {
              MedicalCareType && MedicalCareType.map((medical) => (
                 <Link className='link' to={`/search/medical/${medical._id.toString()}`} key={medical._id}>
              <Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
              <CardContent>
              <Typography variant="h6" color="text.primary">
                        {medical.medicalCareName}
              </Typography>
              </CardContent>
            </Card>
           </Link>
              ))
            }
        </Box>
        </Card>
  </Box>

       
          {/* main card */}
          
          {
            products && products.length === 0 ? <>
                    <Box
                       sx={{
                        minHeight: '350px',
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center'
                      }}>

                        <h2>No result found!</h2>
                    </Box>
            </> :
            <>
            <div className='product-main-container' style={{ display: 'flex', flexDirection: 'column' }}>
           <Box sx={{ flex: 6, p: 1,mt:4 }}>
           <Box sx={{ minHeight: '350px', display: 'flex', justifyContent: 'center', alignItems: 'center',flexDirection: 'column' }}>
              {products.map((product) => (
                <ProductCard key={product._id} product={product} />
              ))}
            </Box>
            <Stack spacing={2} >
            <Pagination variant='outlined' className='pagination' page={page} count={pages === 0 ? 1 : pages} onChange={(event, value) => setPage(value)} />
          </Stack>
          </Box>
          </div>
            </>
          }
        </Stack>
      </Box>
        </>
      }
     
    </div>
  );
};

export default Product;
import './App.css';
import Home from './components/Home/Home';
import Navbar from './components/Navbar/Navbar';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import '../node_modules/bootstrap/dist/js/bootstrap.bundle'
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Login from './components/user/Login';
import Product from './components/product/Product';

function App() {
  return (
    <>
    <Router>
        <Navbar />
        <Routes>
        <Route path='/' element={<Home />} />
        <Route path='/login' element={<Login />} />
        <Route path='/products' element={<Product />} />

        {/* product categories routes */}
        <Route path='/search/treatment/:treatment' element={<Product />} />
        <Route path='/search/essential/:essential' element={<Product />} />
        <Route path='/search/medical/:medical' element={<Product />} />

        </Routes>
    </Router>
       
      
 

    </>
  );
}

export default App;

productAction.js

import axios from 'axios';
import {
    ALL_PRODUCT_REQUEST,
    ALL_PRODUCT_SUCCESS,
    ALL_PRODUCT_FAIL,
    CLEAR_ERRORS
} from "../constants/productConstants"


export const getProduct = (pageNumber,keyword='',animal='',treatment='',essential='',medical='') => async (dispatch)=>
{
    try{
        dispatch({type:ALL_PRODUCT_REQUEST})

        //let link = `/api/v1/products`;
        let link = `/api/v1/products/?pageNumber=${pageNumber}&keyword=${keyword}&animal=${animal}&treatment=${treatment}&essential=${essential}&medical=${medical}`;

        const {data} =  await axios.get(link)
        dispatch({
            type:ALL_PRODUCT_SUCCESS,
            payload:data,
        })

    }
    catch(error){
        dispatch({
            type: ALL_PRODUCT_FAIL,
            payload:error.response.data.message,
        })
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    So It was my mistake the error was in ProductAction.js

    the link would be /api/v1/products/?pageNumber=${pageNumber}&keyword=${keyword}&animal=${animal}&treatment=${treatment}&dailyEssential=${dailyEssential}

    Instead of essentials I should have use dailyEssential

    • same for medical Instead of medical I should have use medicalCare

  2. You should conditionally select which action to dispatch to call the correct/expected backend API. Giving each route a "category" prop to pass to Product will make selecting the correct endpoint easier.

    Example:

    <Route path='/products' element={<Product />} /> // all products? 🤷🏻‍♂️
    <Route
      path='/search/treatment/:id'
      element={<Product category="treatment" />}
    />
    <Route
      path='/search/essential/:id'
      element={<Product category="essential" />}
    />
    <Route
      path='/search/medical/:id'
      element={<Product category="medical" />}
    />
    
    const Product = ({ category }) => {
      const { id, keyword } = useParams(); // I don't see where keyword is defined 🤷🏻‍♂️
    
      ...
    
      useEffect(() => {
        switch(category) {
          case "treatment":
            dispatch(getTreatment(page, id));
            break;
    
          case "essential":
            dispatch(getEssential(page, id));
            break;
    
          case "medical":
            dispatch(getMedical(page, id));
            break;
    
          default:
            dispatch(getProduct(page, keyword, id));
        }
      }, [category, dispatch, page, keyword, id]);
    
      ...
    }
    

    From here each action should fetch its expected data from its respective API and update the appropriate state, either the products state or its own state that would also need to be selected in the Product component to be rendered.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search