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:
THE URL is here: Heroku app
I have tried
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.