When a user updates his profile in editProfile component,the data is updated in the server and the user is redirected to the userProfile component. Now in the userProfile, users data is fetched from the server. Here i am getting the old data. But if i refresh the page, i get the updated data.
//api
router.post('/:uid/edit', (req, res) => {
const updatedUser = {
name : req.body.name,
avatar : req.body.avatar,
bio : req.body.bio
};
console.log('updateduser',updatedUser);
User.findOneAndUpdate({uid: req.params.uid}, {$set: updatedUser},
{"new":true})
.then(user => {
res.json(user);
console.log(user);
})
.catch(err => {
console.log('er',err);
});
});
//action
export const usersFetchData = (url) => {
return (dispatch) => {
dispatch(userIsLoading(true));
axios
.get(url)
.then(res => {
if(!res){
throw Error(res.statusText)
}
dispatch(userIsLoading(false));
console.log(res.data); //getting old data
return res.data;
})
.then(users => {
console.log('users',users);
dispatch(usersFetchDataSuccess(users))
})
.catch(() => dispatch(userHasErrored(true)));
}
}
Most likely this is due to axios caching. See what you have in the axios settings and if
'Cache-Control': 'no-cache'
is set. Usually via:
var config = {headers: {'Content-Type': 'application/json','Cache-Control' : 'no-cache'}};
axios.get('/get', config) // <-- config
If this does not work you can always just append a timestamp to the request to make sure it always makes a request.
Related
I can't seem to get why my Login component is getting an error when my Registration component works well while using the same POST request to the backend server. The only thing that they differ is the method of retrieving data from MongoDB in their backend script partner, which is what I am thinking is the problem, but anything I do doesn't seem to work.
Edit > * The error in the Login Component is AxiosError: Network Error. Both the Login and Register backend have been tested in Postman and works well, and responds a status. So it seems that the problem is in the Login React Component's Axios post request. It send data to the backend okay, but it catches an error after that.*
The login script of the backend server is working well and validating the credentials perfectly. But then, React gets an error.
in Login React Component (AxiosError):
async postReq() {
const loginData = JSON.stringify(
{
'email': this.state.email,
'password': this.state.password,
},
);
console.log(loginData)
let validation = await axios.post(
'http://localhost:5000/login',
loginData,
{ headers: {'Content-Type':'application/json'}
})
.then((res) => {
console.log(`Login successful. ${res}`);
let response = res;
this.props.redirect('/session');
})
.catch((error) => {
console.log(error);
console.log(`Cannot login. ${error.message}`)
console.log(error.request);
let response = error;
alert("Damn.")
});
}
in Register React Component (works smoothly):
handleSubmit() {
// POST to server
const regData = JSON.stringify(
{
'firstname': this.state.fname,
'lastname': this.state.lname,
'email': this.state.email,
'birthday': this.state.birthday,
'password': this.state.password,
'country': this.state.country,
'city': this.state.city,
'provstate': this.state.provstate,
'contactnum': this.state.contactnum,
'formpicture': this.state.img,
'disclcond': this.state.cond,
},
);
console.log(regData)
axios.post(
'http://localhost:5000/register',
regData,
{ headers: {'Content-Type':'application/json'}
})
.then((res) => {
console.log(`Registered successfully. ${res}`);
setTimeout(() => this.props.redirect('/login'), 2000)
})
.catch((res) => {
console.log(`Not registered. ${res}`)
alert("Damn.")
});
}
NodeJS, Mongoose || Login backend:
const router = require('express').Router();
let User = require('../db_models/user.model');
router.route('/').get((req, res) => {
res.sendStatus(200);
res.end();
})
// If user submits login credentials, check database
router.route('/').post((req, res) => {
const email = req.body.email;
console.log(email)
const password = req.body.password;
let accountMatched = null;
async function checkPassword() {
await User.findOne({ 'email' : email })
.then(user => {
if (user.password === password) {
console.log(`true ${user.email} :: ${user.password}`);
accountMatched = true;
res.sendStatus(200);
} else {
console.log(`damn!! ${err}`)
res.sendStatus(404);
throw err
}
})
.catch(err => console.log(err))
accountMatched === true ? console.log('Passed') : res.send('Failed');
res.end()
}
checkPassword();
})
module.exports = router;
Register backend:
const router = require('express').Router();
let User = require('../db_models/user.model');
router.route('/').get((req, res) => {
res.send('hello hello');
res.end();
})
// If user submits registration credentials, submit to database
router.route('/').post((req, res) => {
console.log(req.body)
const firstname = req.body.firstname;
const lastname = req.body.lastname;
const email = req.body.email;
const birthday = Date.parse(req.body.birthday);
const password = req.body.password;
const contactnum = req.body.contactnum;
const country = req.body.country;
const city = req.body.city;
const provstate = req.body.provstate;
// below only pass links
const formpicture = req.body.formpicture;
const disclcond = req.body.disclcond;
const newUser = new User({
firstname,
lastname,
email,
birthday,
password,
country,
city,
provstate,
contactnum,
formpicture,
disclcond,
});
newUser.save()
.then(() => {
console.log('User added.');
res.sendStatus(200);
res.end();
})
.catch(err => {
console.log(`Damn, user not added. ${err}`);
res.end();
})
});
module.exports = router;
I would really appreciate some help.
Try exchange the Login Component part to something like this if you wanna use async/await.
async postReq() {
const loginData = JSON.stringify(
{
'email': this.state.email,
'password': this.state.password,
},
);
console.log(loginData)
try {
let res = await axios.post(
'http://localhost:5000/login',
loginData,
{ headers: {'Content-Type':'application/json'}
})
console.log(`Login successful. ${res}`);
let response = res;
this.props.redirect('/session');
} catch (error) {
console.log(error);
console.log(`Cannot login. ${error.message}`)
console.log(error.request);
let response = error;
alert("Damn.")
}
}
my backend send a res.staus(200).json({somedata)} to my front, but i can't retrieve the data in the frontend.
My backend :
exports.login = (req, res, next) => {
//===== Check if user exists in DB ======
const { user_email, user_password: clearPassword } = req.body;
let sql = `SELECT user_password, user_id FROM users WHERE user_email=?`;
db.query(sql, [user_email], async (err, results) => {
console.log(results);
console.log(req.body);
if (err) {
return res.status(404).json({ err });
}
// ===== Verify password with hash in DB ======
const { user_password: hashedPassword, user_id } = results[0];
try {
const match = await bcrypt.compare(clearPassword, hashedPassword);
if (match) {
console.log("match ... user_id : ", user_id);
// If match, generate JWT token
res.status(200).json({
test: 'iyu',
user_id: user_id,
token: jwt.sign({ userId: user_id }, "TOOOKEN", {
expiresIn: "24h",
}),
});
} else {
console.log("not match");
}
} catch (err) {
return res.status(400).json({ err: "une erreur" });
}
});
};
The frontend :
const login = async (e) => {
e.preventDefault();
await POST(ENDPOINTS.USER_LOGIN, userLogin);
// await GET(ENDPOINTS.USER_LOGIN)
fetch("http://localhost:4200/api/auth/login")
.then((response) => response.json())
.then((data) => {
console.log(data);
});
};
This login fonction send data to my backend, then the backend checks if an user exist in database with the first POST request. If yes, the backend send in json format some data that i wan't to put in the local storage of the user, so after the POST request, i do another request with GET method to retrieve the json data sent from the back, but i have an 404 error.
How can i get my data sent by the back ?
Seems the problem is with the SQL statement, underneath the if statement you have can you print the error like so:
if(err) {
console.log(err);
}
and tell me the result please
I've created a React app where you can post vinyls you have in your collection. Now I've implemented a button that is able to remove the selected item from the DOM but I also want the specific item to beremoved from the database. I'm using node with mongoose and that's (for now) my delete route:
vinylsRouter.delete('/:id', (req, res) => {
const id = req.params.id
Vinyl.findByIdAndDelete(id)
.then((deletedVinyl) => {
console.log(deletedVinyl)
})
.catch((error) => {
res.status(500).send(error);
})
});
I also tried to store the id of the specific vinyl _id into a variable and then delete it. So I also created a get route to try to get the _id of the vinyl.
vinylsRouter.get('/:id', authenticateJWT, (req, res) => {
const id = req.params.id;
Vinyl.findById(id, { __v: 0, updatedAt: 0, createdAt: 0 })
.then((user) => {
res.send(user)
})
.catch((error) => {
res.status(500).send(error)
})
});
But now I don't know how to code in the client side to make that when an user clicks in the delete button, it sends something to get the id of the vinyl and then delete it.
First put some response when the delete works:
vinylsRouter.delete('/:id', (req, res) => {
const id = req.params.id
Vinyl.findByIdAndDelete(id)
.then((deletedVinyl) => {
res.status(200).send(deletedVinyl);
})
.catch((error) => {
res.status(500).send(error);
})
});
If are you trying to do a API You can use express/nodejs, and do res.status(200).json({message: "my message"}).
Second you can use a library like axios:
axios.delete(`http://localhost:xyz/vynils/`, { id })
.then(res => {
console.log(res);
console.log(res.data);
})
https://www.digitalocean.com/community/tutorials/react-axios-react
And send for the server when the users click in the delete button.
You can use postman to test your delete endpoint before you use this on client-side (frontend), remember select delete in the dropbox and put a auth token (JWT) in the Authorization tab, or you can remove, only for test the auth middleware:
Say me if is this what you want to do.
app.delete('/product/:id', async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await productCollection.deleteOne(query);
res.send(result);
})
I'm having a little issue. I'm developing an app and I created API with node.js(using express). Right now I'm trying to send my error objects from node to react but for some reason I cannot get it. I can see the object in the network tab but I want to use it, like console it to the client.
back-end:
app.post('/api/users/login', async (req, res) => {
try {
const user = await User.findByCredentials({ ...req.body });
const token = await user.generateAuthToken();
res
.cookie('w_auth', token)
.status(200)
.send({ user, token });
} catch (error) {
res.status(400).send({ success: false, error: 'some error' });
}
});
client-side:
loginUser:
export const loginUser = dataToSubmit => {
return axios.post(`${USER_SERVER}/login`, dataToSubmit);
};
loginUser(dataToSubmit)
.then(res => {
console.log(res);
dispatch({ type: 'SET_USER', user: res.data.user });
})
.catch(error => {
console.log(error);
});
I tried also just send a respond without error from back-end which also didn't work.
picture of what I get:
network tab:
You can catch it the below way.
axios
.post(url, data)
.then(response => {
//You get success response here.
})
.catch(err => {
//Error response here
});
Axios Post request
// Create profile
export const createProfile = (profileData, avatar, history) => dispatch => {
dispatch(clearErrors());
const image = new FormData();
image.append("avatar", avatar, avatar.name);
axios
.post("/api/profile", image, profileData)
.then(res => history.push("/dashboard"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
Edit ---> Axios post request second attempt
// Create profile
export const createProfile = (profileData, avatar, history) => dispatch => {
dispatch(clearErrors());
const image = new FormData();
image.append("avatar", avatar, avatar.name);
image.append("user", profileData, profileData.username);
axios
.post("/api/profile", image)
.then(res => history.push("/dashboard"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
profileData is what i want in the req.body and avatar is what i receive in req.file in my back-end with multer, but what i receive is the req.file with the image but nothing in my req.body(Just an empty object)
This is my router in node
router.post(
"/",
upload.single("avatar"),
passport.authenticate("jwt", { session: false }),
(req, res) => {
console.log(req.body);
}
);
Try to implement in following way using FormData
handleSubmit(e)
{
e.preventDefault();
const err = this.validate();
if (!err) {
var formData = {
category: this.state.category,
course: this.state.course,
};
const { category, course } = this.state;
let fd = new FormData();
fd.append('Test', this.state.testFile, this.state.testFile.name);
fd.append('category', category);
fd.append('course', course);
console.log(fd);
axios({
method: 'post',
url: 'http://localhost:7777/api/uploadTest',
data: fd,
})
.then((response) => {
if (response.data == 'Success') {
alert('Test has been Added..!!');
}
else {
alert('Something went wrong');
this.setState({ category: '' });
}
// this.setState({success:'Alert: '+response.data});
})
.catch((e) => {
console.error(e);
this.setState({ success: 'Alert: Something went wrong' });
});
}
}
I consider your route as /api/profile in route file.
You don't show your header profileData.
It should be like this
const profileData = {
headers: { 'content-type': 'multipart/form-data' }
}
Then you can request to the server as you already did.