NodeJS 我想根据搜索查询更新产品列表,我的治疗卡工作正常,但不是必需品和医疗

8ulbf1ek  于 2023-05-06  发布在  Node.js
关注(0)|答案(2)|浏览(101)

我有4个类别anmialtreatmentdailyEssentialsmedical-care
在左侧有3个卡为treatmentdailyEssentialsmedical-care和一个下拉菜单选择animals
该产品得到更新完美的Animaltreatment类别,但dailyEssentialsmedical-care不给所需的产品作为输出,而不是它的显示所有的产品.
网址-http://localhost:3000/search/essential/6451eafc000f972917fe38fe

  • 6451eafc000f972917fe38fe是每日必不可少的类别ID。

我有一个问题,treatment卡是非常相似的dailyEssentialsmedical-care在我的情况下treatment是工作正常,那么为什么不dailyEssentialsmedical-care
这是后端

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

基本操作

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

基本还原剂

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,
        })
    }
}
olhwl3o2

olhwl3o21#

所以这是我的错误错误是在ProductAction.js
链接为/api/v1/products/?pageNumber=${pageNumber}&keyword=${keyword}&animal=${animal}&treatment=${treatment}&dailyEssential=${dailyEssential}
而不是essentials我应该使用dailyEssential

  • 对于医疗也是一样,而不是medical,我应该使用medicalCare
avwztpqn

avwztpqn2#

您应该有条件地选择要分派哪个操作来调用正确/预期的后端API。为每个路由指定一个“类别”属性以传递给Product,这样可以更容易地选择正确的端点。
示例:

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

  ...
}

从这里开始,每个动作都应该从各自的API中获取预期的数据,并更新相应的状态,要么是products状态,要么是它自己的状态,这些状态也需要在Product组件中选择才能呈现。

相关问题