简体   繁体   中英

req.query from backend turns out to be json on React front end after deployed to heroku, how to fix it?

This question is closely related to This

Backend:

//route: GET /shop
//note: get all the products on shop page
//access: public
router.get('/', async (req, res) => {
    try {
        let items

        //sort by category
        if(!req.query.category) {
            items = await Product.find()
        } else {
            items = await Product.find({category: req.query.category})
        }
        //sort by price and letter
        if(req.query.sortBy) {
            let sort ={}
            const sortByArray = req.query.sortBy.split(':')
            sort[sortByArray[0]] =[sortByArray[1]]
            items = await Product.find().sort(sort).exec()
        }

        res.json(items)
    } catch (error) {
        console.error(error.message)
        res.status(500).send('Server error')
    }
})

actions:

//get all the products
export const getProducts = () => async dispatch => {
    try {
        const res = await axios.get(`/shop${window.location.search}`)

        dispatch({
            type: GET_PRODUCTS,
            payload: res.data
        })
    } catch (error) {
        dispatch({
            type: PRODUCT_ERROR,
            payload: { msg: error.response.statusText, status: error.response.status }
        })
    }
}

front-end for the filter links:

<a href="/shop?category=music" >MUSIC</a>

How I get products rendering from front-end

import React, {useEffect, Fragment } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'

import Loader from '../layout/Loader'
import ProductItem from './ProductItem'

import { getProducts } from '../../actions/products'
import { addToCart } from '../../actions/cart'


const Products = ({
    getProducts,
    addToCart,
    product: {
        products,
        loading
    }
}) => {

    useEffect(() => {
        getProducts()
    }, [getProducts])

    return  loading ? <Loader /> : (
        <Fragment>
            <section className="products-grid">
            {products.map(product => (
                <ProductItem key={product._id} product={product} addToCart={addToCart} />
            ))}
            </section>
        </Fragment>
    )

}

Products.propTypes = {
    product: PropTypes.object.isRequired,
    getProducts: PropTypes.func.isRequired,
    addToCart: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
    product: state.product
})

export default connect(mapStateToProps, {getProducts, addToCart})(Products)

It works well in my development environment, when click on music I get it filtered like this: 当地环境 then I deployed to heruko (that means we run build etc). Now on the deployed version, when I clicked on my filtering options, they turn out to be json string, like we're getting the response from backend directly to the browser, like this: Heroku

THE URL is here: Heroku app

I have tried

  1. adding the deployed address to the axios.get, but it didn't work
  2. changing the proxy in client's json file (before it's http://localhost:5000 ) to the deployed app address, it didn't work either

So how do I fix this problem so it works exactly like in my dev environment?

It looks like your problem is that your backend has the same url as your frontend . Which means that, when you enter the app through myurl.com/ it will work, but if you refresh the page in lets say myurl.com/shop it will try to access the backend api.

One way to try and solve this could be to append /api on the backend requests. So you would get

router.get('/api', async (req, res) => {...}

and on front

const res = await axios.get(`/api/shop${window.location.search}`)

It might not solve everything though, but it's worth a try.

I don't have a clear info on how your structure is set, but you also might need to make a few changes in the entire frontend/backend communication.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM