redux Expressjs未将发送的数据作为字符串读取

7y4bm7vi  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(112)

我正在用MERN(MongoDB ExpressJs ReactJs NodeJs)构建一个应用程序,我正在使用put请求向我的URL发送确认数据,并检查它是否为:“received”、“canceled”或“processing”。但挑战在于,我正在比较它,如下面的控制器代码所示,但我的函数读取的值是不同的值,即使我正在发送上面提到的值之一。下面是我从前端到后端的代码。
更新状态URL终结点

// @Route   PUT api/orders/id/item_id
// @Desc    Route for updating order status
// @Access  Private
router.put('/:id/:item_id', [
    auth,
    body('newstatus','The new status cannot be empty').not().isEmpty()
], orderControllers.updateOrderStatus);

UpdateStatus控制器函数

// The controller for updating order status
const updateOrderStatus = async (req, res) => {
    const error = validationResult(req);
    // Check for errors in the body request
    if (!error.isEmpty()) {
        return res.status(400).json(error.errors[0]);
    }
    const { newstatus } = req.body;
    const { id, item_id } = req.params;
    try {
        // Get user account
        const user = await User.findById(req.user.id);
        // Check if user account exists
        if (!user) {
            return res.status(401).json({
                msg: 'You are not authorized to make use of this feature.',
                status: 'unauthorized',
                status_code: '401'
            });
        }

        // Get the order data
        const order = await Order.findById(id);
        if (!order) {
            return res.status(404).json({
                msg: 'The order you are trying to update does not exist.',
                status: 'not found',
                status_code: '404'
            });
        }
        if (newstatus !== 'received' || 'cancelled' || 'processing') {
            return res.status(400).json({
                msg: 'Wrong purchase status detected.',
                status: 'bad request',
                status_code: '400'
            });
        }
        // Get order object
        const orderObject = order.goodspurchased.find(item => item._id.toString() === item_id);
        // Update order status
        order.goodspurchased.map(item => item._id.toString() === item_id ? item.status = newstatus : item);
        // Save order
        await order.save();
        // Get the vendor wallet
        const wallet = await pool.query('SELECT * FROM wallet WHERE store_id=$1',[orderObject.storeid]);
        // Check status
        if (newstatus === 'received' && orderObject.status === 'processing') {
            // Create new available balance and ledger balance
            const availableBalance = wallet.rows[0].available_balance + parseFloat(orderObject.cost);
            const ledgerBalance = wallet.rows[0].ledger_balance - parseFloat(orderObject.cost);
            // Update the vendor wallet balance
            await pool.query('UPDATE wallet SET available_balance=$1, ledger_balance=$2 WHERE store_id=$3', [availableBalance, ledgerBalance, orderObject.storeid]);
            return res.status(200).json({
                msg: 'You have successfully confirmed the receival of this product.',
                status: 'success',
                status_code: '200',
                order_status: 'received',
                item_id
            });
        } else if (newstatus === 'cancelled' && orderObject.status === 'processing') {
            let goods;
            if (order.goodspurchased.length > 1) {
                goods = 'items';
            } else {
                goods = 'item';
            }
            // Create new ledger balance
            const ledgerBalance = wallet.rows[0].ledger_balance - parseFloat(orderObject.cost);
            // Update the vendor wallet balance
            await pool.query('UPDATE wallet SET ledger_balance=$1 WHERE store_id=$2', [ledgerBalance, orderObject.storeid]);
            // Send notification sms to the customer that their purchase has been cancelled and their funds have refunded to their account
            await client.messages.create({
                body: `Hi ${order.customerfirstname} ${order.customerlastname}, your order for the purchase of ${order.goodspurchased.length} ${goods} has been cancelled and your funds are been processed. Thank you once more for using quickstore.`,
                from: '+12075033646',
                to: `${order.customerphone}`
            });
            // Return success response
            return res.status(200).json({
                msg: 'Your have successfully cancelled this order and your funds are been processed.',
                status: 'success',
                status_code: '200',
                order_status: 'cancelled',
                item_id
            });
        } else if (orderObject.status !== 'processing') {
            return res.status(200).json({
                msg: 'You have already confirmed this order.',
                status: 'success',
                status_code: '200',
                order_status: orderObject.status,
                item_id
            });
        }
    } catch (error) {
        // Check for server error
        if (error) {
            return res.status(503).json({
                msg: 'We encountered an error while confirming your order. Please try again later, thank you.',
                status: 'service unavailable',
                status_code: '503'
            });
        }
    }
}

UpdateInvoice还原状态变元函数

export const updateInvoice = createAsyncThunk(
    "order/updateInvoiceStatus",
    async (orderData, { rejectWithValue }) => {
        try {
            const { id, item_id, data } = orderData;
            const response = await orderAPI.updateInvoiceStatus(id, item_id, data);
            return response.data;
        } catch (error) {
            return rejectWithValue(error.response.data);
        }
    }
);

OrderAPI.updateInvoiceStatus

export const updateInvoiceStatus = (id, item_id, data) => {
    const token = localStorage.getItem("token");
    if (token) {
        setAuthToken(token);
    }
    return axios.put(`http://localhost:5000/api/orders/${id}/${item_id}`, JSON.stringify({ newstatus: data }), headerConfig);
}

发票组件

import { useEffect, useState, Fragment } from 'react';
import Header from '../components/layout/Header';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCancel, faCheck } from '@fortawesome/free-solid-svg-icons';
import { useParams } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { getInvoice, updateInvoice, clearOrderMessages } from '../reducers/orderSlice';
import SmallButton from '../components/layout/SmallButton';

const Invoice = () => {
    const [ goods, setGoods ] = useState([]);
    const { invoice, message } = useSelector(state => state.order);
    const dispatch = useDispatch();
    const { id } = useParams();

    useEffect(() => {
        dispatch(getInvoice(id));
    },[id, dispatch]);

    useEffect(() => {
        if (invoice && invoice.goodspurchased && goods.length === 0) {
            setGoods(invoice.goodspurchased);
        }
        if (JSON.stringify(message) !== '{}' && message.order_status !== 'processing') {
            setGoods(goods.map(item => item._id === message.item_id ? { ...item, status: message.order_status } : item));
            dispatch(clearOrderMessages());
        }
    },[dispatch, invoice, message, goods]);

    const updateStatus = (e, id, item_id, status) => {
        e.preventDefault();
        const data = {
            id: id,
            item_id: item_id,
            data: status
        };
        // console.log(data);
        dispatch(updateInvoice(data));
    }

    const total = (goods) => {
        let cost = 0;
        if (goods && goods.length > 0) {
            for (let i = 0; i < goods.length; i++) {
                cost += goods[i].cost;
            }
            return cost;
        }
    }
    
    return (
        <div style={{ overflowX: 'scroll', overflowY: 'auto', marginTop: '10px' }} className='invoice'>
            <Header text='Receipt' />
            <table style={{ marginTop: '5px' }}>
                <thead>
                    <tr>
                        <th>Serial #</th>
                        <th>Store ID</th>
                        <th>Product name</th>
                        <th>Status</th>
                        <th>Confirm/Reject</th>
                        <th>Price ($)</th>
                        <th>Quantity</th>
                        <th>Cost ($)</th>
                    </tr>
                </thead>
                <tbody>
                    {goods && goods.map((item, index) => (
                        <tr key={item.productid}>
                            <td>{index + 1}</td>
                            <td>{item.storeid}</td>
                            <td>{item.productname}</td>
                            <td>{item.status}</td>
                            <td>
                                {item.status === 'processing' ? (
                                    <Fragment>
                                        <button onClick={(e) => updateStatus(e, invoice._id, item._id, 'received')} style={{ backgroundColor: 'rgba(3, 201, 53, 0.8)', padding: '5px', borderRadius: '5px', border: '0px', marginRight: '10px' }}>
                                            <FontAwesomeIcon style={iconStyle} className='clickable-icon-style' icon={faCheck} />
                                        </button>
                                        <button onClick={(e) => updateStatus(e, invoice._id, item._id, 'cancelled')} style={{ backgroundColor: '#F55050', padding: '5px', borderRadius: '5px', border: '0px'  }}>
                                            <FontAwesomeIcon style={iconStyle} className='clickable-icon-style' icon={faCancel} />
                                        </button>
                                    </Fragment>
                                ) : (
                                <Fragment>
                                    <button disabled style={{ backgroundColor: '#e3e6e7', padding: '5px', borderRadius: '5px', border: '0px', marginRight: '10px' }}>
                                        <FontAwesomeIcon style={iconStyle} className='clickable-icon-style' icon={faCheck} />
                                    </button>
                                    <button disabled style={{ backgroundColor: '#e3e6e7', padding: '5px', borderRadius: '5px', border: '0px'  }}>
                                        <FontAwesomeIcon style={iconStyle} className='clickable-icon-style' icon={faCancel} />
                                    </button>
                                </Fragment>
                                )}
                            </td>
                            <td>{item.price}</td>
                            <td>{item.quantity}</td>
                            <td>{item.cost}</td>
                        </tr>
                    ))}
                    <tr>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td></td>
                        <td>Total</td>
                        <td><b>{total(invoice.goodspurchased)}</b></td>
                    </tr>
                </tbody>
            </table>
        </div>
    )
}

const iconStyle = {
    color: '#ffffff'
}

export default Invoice;

即使当我发送“已收到”,我的expressjs后端仍然说“检测到错误的购买状态。"请我需要有人来帮助我解决这个错误。

mdfafbf1

mdfafbf11#

为什么要把数据转换成字符串?因为在用JSON.stringify请求的时候,我们把对象{ newstatus: data }转换成字符串,在控制器中const { newstatus } = req.body不会像你期望的那样工作,因为它不是一个对象。newstatus是未定义的。在这种情况下,我会删除axios请求中的JSON.stringify,只发送带有newstatus属性的对象。
为了让你在将来更容易发现这类错误,我会在检查之前添加console.log,看看是什么值导致它进入那个条件。在你的例子中,因为你提到你得到了错误'检测到错误的购买状态'。这意味着你的newstatus值有问题。
我想把这作为一个评论加进去。希望它能对你有所帮助。

相关问题