Reputation: 496
I know there are a lot of other "works in postman and not in browser" posts, but I've read through them and cannot find anything to give direction on what I'm not catching here. Most of those had to do with proxy issues, but I dont have any proxy's set up.
I recently changed from using a pymongo backend to mongoose/express. My find() works for the get all clients just fine on the browser side, but the findOne() get comes back undefined (I was getting an unexpected token JSON error but that is resolved although I dont know what actually fixed it), yet in Postman it brings exactly what I'm looking for. I'm assuming its something simple, but I can't seem to spot it.
Backend- index.js
const express = require("express")
const mongoose = require("mongoose")
const cors = require('cors')
const clientRoutes = require("./routes/clientRoutes")
const contractRoutes = require("./routes/contractRoutes")
const bodyParser = require('body-parser');
mongoose
.connect("MONGODB URL", { useNewUrlParser: true })
.then(() => {
const app = express()
app.use(express.json())
app.use(cors())
app.use(bodyParser.json());
app.use("/api", clientRoutes)
app.use("/api", contractRoutes)
app.listen(5000, () => {
console.log("Server has started")
})
})
Schema
const mongoose = require("mongoose")
const schema = mongoose.Schema({
clientId: Number,
firstName: String,
lastName: String,
phone: String,
contracts: [{
contractId: Number,
authNumber: String,
contType: String,
contHours: Number,
contStartDate: Date,
contEndDate: Date
}],
})
module.exports = mongoose.model("Client", schema)
routes-
const express = require("express")
const Client = require("../models/Client.js")
const router = express.Router()
//Client routes
router.get("/clients", async (req, res) => {
const clients = await Client.find()
res.send(clients)
})
router.get("/clients/:clientId", async (req, res) => {
try {
const client = await Client.findOne({ clientId: req.params.clientId })
res.send(client)
} catch {
res.status(404)
res.send({ error: "Client not found"})
}
})
React frontend component making the request-
import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import ChartNav from './ChartNav';
import ClientContext from './ClientContext';
class ClientChart extends React.Component {
static get propTypes() {
return {
match: PropTypes.any,
clientId: PropTypes.any
}
}
constructor (props){
super(props);
this.state = {
clientId: this.props.match.params.clientId,
client: {},
isLoading: true,
errors: null
};
console.log(this.state.clientId)
}
componentDidMount(){
fetch(`http://localhost:5000/api/clients/${this.state.clientId}`)
.then(res => res.json())
.then(
result => {
let client = JSON.parse(result.data);
this.setState({
isLoading: false,
client: client,
});
}, [])
.catch(error => this.setState({
error: error.message,
isLoading: false,
}));
}
console and response
404
XHR GET http://localhost:5000/api/clients/undefined
error "Client not found"
Upvotes: 0
Views: 845
Reputation: 496
So in trying to track it down, I switched clientId back to id (which I had been using previously, and changed the prop in the DB for 1 client back to id to test), and calling console.log after the initial response from the fetch showed the data coming through. When I setState from that initial response, all props populated where they should. In reverting the id back to clientId and changing the routes, and using a client with the clientId field, etc., nothing works again. So if anyone knows why React is happy with id but not clientId as an identifier, please let me know. Even weirder is that its able to call all the other clients who I still have listed with clientId, and the routes are calling by clientId, not id... so Im at a total loss as to whats happening under the hood.
Below is the working get call (I also threw in axios at one point in trying to track it down and left it there, but initially it did not make any difference).
axios.get(`http://localhost:5000/api/clients/${this.state.id}`)
.then((response) => {
const data = response.data;
console.log(response.data);
this.setState({
client: data,
isLoading: false,
});
}, [])
Upvotes: 1