Axios in Nuxt.js is not catch error properly - axios

As I mentioned above my Axios on Nuxt.js is not catch error properly
I need to know the error, so I can prompt to let the user know their input is not correct but it only console.log the error code status not the message from my API
this is my code
await axios
.post(
"API LINK",
{
email: user.email,
password: "123456",
name: user.name,
dob: user.dob ?? null,
gender: user.gender ?? null,
profileImage: imageUrl ?? user.profileImage,
userType: user.userType
}
)
.then(res => {
console.log("success");
console.log(res);
})
.catch(err => {
console.log('fail');
console.log(err)
})
This is what log on a chrome console
error
add.vue?104b:181 Error: Request failed with status code 400
at createError (createError.js?2d83:16)
at settle (settle.js?467f:17)
at XMLHttpRequest.handleLoad (xhr.js?b50d:61)
But what I expect from the console.log(err) is
(This is response from postman)
{
"message": "Error creating new user.",
"error": {
"code": "auth/invalid-password",
"message": "The password must be a string with at least 6 characters."
}
}
I have no idea what is happening.

Try this
console.log(err.response)
To make the code cleaner you can destructure the argument:
.catch(({ response }) => {
console.log('fail');
console.log(response)
})
If you want to use some other property name instead of response you can do it like this:
.catch(({ response: err }) => {
console.log('fail');
console.log(err)
})
The problem is when the console.log tries to output the error, the string representation is printed, not the object structure, so you do not see the .response property.
Here you can read about https://github.com/axios/axios/issues/960

This is working with a try / catch structure, which is the preferred way
try {
await axios.post("API LINK", {
email: user.email,
password: "123456",
name: user.name,
dob: user.dob ?? null,
gender: user.gender ?? null,
profileImage: imageUrl ?? user.profileImage,
userType: user.userType,
})
console.log("success", res)
} catch ({ response }) {
console.log("fail", response)
}

Related

{status: false, message: Not Authorized, date: null}

I get this in my flutter app, I send the token but still get this error message and everything is supposed to be alright
void changeFavourites(int productId) {
DioHelper.postData(
url: favourite,
data: {"product_id": productId},
lang: "en",
token: token,
).then((value) {
changeFavouritesmodel = ChangeFavouritesmodel.fromJson(value.data);
print(value.data);
print(token);
emit(ShopChangeFavouritesSuccessState());
}).catchError((error) {
emit(ShopChangeFavouritesErrorState());
});
}

Empty data in response with axios and vuex

When I send this patch request with axios, the backend receives the data, but response.data comes back empty. Please and thanks!
// ACTION IN VUEX STORE
async updateMe({ commit }, payload) {
let id = localStorage.getItem('userId');
let user = { name: payload.name, email: payload.email, id: id };
try {
const response = await axios.patch(
`http://localhost:3000/api/v1/users/updateMe`,
user
);
commit('setUpdatedUser', response.data);
} catch (err) {
console.log(err);
}
}
// CONTROLLER
exports.updateMe = catchAsync(async (req, res, next) => {
const updatedUser = await User.findByIdAndUpdate(
req.body.id,
{
name: req.body.name,
email: req.body.email
},
{ new: true, runValidators: true }
);
res.status(204).json({ data: updatedUser });
});
204 is a No Content response code.

How to get signed in users data?

I have a MERN mobile app thats using passportjs to authenticate and login users (with mongodb database and axios), however, when i eventually get to the the screen to enter in data (a "log"), i cant associate that data/log with the signed in user. How can i grab the user id several screens later after they have already signed in to associate it with the entry? My mongodb database has a number of users, so i only want a specific user's data (eg calories), ie the one that is currently logged in:
// Mongoose schemas
// log.model.js
const Schema = mongoose.Schema;
const logSchema = new Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
calories: {
type: Number,
required: true,
},
},
{
timestamps: true,
}
);
const Log = mongoose.model("Log", logSchema);
// user.model.js
const userSchema = new Schema(
{
_id: Schema.Types.ObjectId, // user id
email: {
type: String,
required: true,
unique: true,
trim: true,
},
password: {
type: String,
required: true,
trim: true,
minlength: 6,
},
},
{
timestamps: true,
}
);
const User = mongoose.model("User", userSchema);
They are first prompted to signin in the app, where they will then navigate to Home. Not all features are added in yet, just in development stage now:
// ./frontend/screens/signin.js
function onLoginPress() {
axios({
method: "POST",
data: {
email: email,
password: password,
},
withCredentials: true,
url: 'http:localhost:5000/users/signin',
})
.then((res) => console.log(res.data))
.catch((error) =>
console.log("ERROR: Promise rejected (sign in): " + error)
);
navigation.navigate("Home");
}
// ./backend/routes/users.js
router.route("/signin").post((req, res, next) => {
passport.authenticate("local", (error, user, info) => {
if (error) {
res.json({
status: "FAILED",
message: error,
});
}
if (!user) {
res.json({
status: "FAILED",
message: "No user exists",
});
} else {
req.logIn(user, (error) => {
if (error) console.log("ERROR: " + error);
res.json({
status: "SUCCESS",
message: "Successfully authenticated",
});
console.log(req.user);
});
}
})(req, res, next);
});
After they sign in, and they wish to enter in calories, i attempt to associate that log (and any future logs they might add) with the signed in user when they hit a button:
// ./frontend/screens/log.js
const [calories, setCalories] = React.useState("");
function onSaveLog() {
axios({
method: "post",
url: "http://localhost:5000/log/add",
data: {
calories: calories,
// CANT GET USER ID HERE?
},
})
.then((res) => {
console.log(res.data);
})
.catch(function () {
console.log("LOG ERROR: promise rejected");
});
}
// ./backend/routes/log.js
router.route("/add").post((req, res) => {
const calories = Number(req.body.calories);
// const user = req.body.user; // CANT GET THE USER ID HERE
const newLog = new Log({
calories,
// user,
});
// saves Log data to mongodb
newLog
.save()
.then(() => res.json("Log added"))
.catch((err) => res.status(400).json("Error: " + err));
});
so, what you doubt is, correct me if I'm wrong is that you want an ID that can be accessed somewhere later in the app to retrieve the users' data.
There are many ways to achieve that,
after you get the id, you can pass it as Navparams. check this for more info RN- params
Next you can store the id in async storage and retrieve it anywhere, I would suggest this cause is the easiest rn--async storage
import AsyncStorage from '#react-native-async-storage/async-storage';
const storeData = async (value) => {
try {
await AsyncStorage.setItem('#storage_Key', value)
} catch (e) {
// saving error
}
}
// read
const getData = async () => {
try {
const value = await AsyncStorage.getItem('#storage_Key')
if(value !== null) {
// value previously stored
}
} catch(e) {
// error reading value
}
}
you can do it this way, do tell me if you're stuck

I am getting this error : Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

When I am sending POST Request for Login, then show this Error. I have used mongoose & MongoDB Atlas.
If I send POST request with valid email & password, it also shows this error.
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent
to the client
But POST request for registration is working well.
User Model
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const userSchema = new Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true
},
balance: Number,
income: Number,
expense: Number,
transactions: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Transaction'
}]
}
})
const User = mongoose.model('User', userSchema)
module.exports = User
User Controller
const registorValidate = require('../validator/registrationValidate')
const User = require('../models/userModel')
const bcrypt = require('bcrypt')
const loginValidate = require('../validator/loginValidator')
const jwt = require('jsonwebtoken')
module.exports = {
login: (req, res) => {
const { email, password } = req.body
let logValidate = loginValidate({ email, password })
if (!logValidate.isValid) {
res.status(400).json(logValidate.error)
return
}
User.findOne({ email })
.then(user => {
if (!user) {
console.log(`${email} not found`)
res.json({
msg: `${email} not found`
})
}
bcrypt.compare(password, user.password, (err, result) => {
if (err) {
res.status(400).json({
msg: 'Error occured'
})
}
if (!result) {
res.status(404).json({
msg: `Password doesn't match`
})
}
let token = jwt.sign({
_id: user._id,
name: user.name,
email: user.email
}, 'SECRET', { expiresIn: '2h' })
res.status(200).json({
msg: 'Login successful',
token: `Bearer ${token}`
})
})
return
})
.catch(err => {
res.status(500).json({
msg: 'Error occured'
})
})
res.end()
},
registration: (req, res) => {
let { name, email, password, confirmPassword } = req.body
let validate = registorValidate({ name, email, password, confirmPassword })
if (!validate.isValid) {
res.status(400).json(validate.error)
} else {
User.findOne({ email })
.then(user => {
if (user) {
res.json({
msg: `${email} is already exist`
})
} else {
bcrypt.hash(password, 11, (err, hash) => {
if (err) {
res.status(500).json({
msg: 'Server error occured'
})
}
let user = new User({
name,
email,
password: hash
})
user.save()
.then(user => {
res.status(201).json({
msg: `Thanks ${name} for your registration`,
user
})
})
.catch(err => {
res.status(500).json({
msg: 'Error occured'
})
})
})
}
})
.catch(err => {
res.status(500).json({
msg: 'Error occured'
})
})
}
}
}
Login Validator
const validator = require('validator')
const validate = user => {
let error = {}
// Email validator
if (!user.email) {
error.email = 'Please provide an Email'
} else if (!validator.isEmail(user.email)) {
error.email = 'Please provide a valid Email'
}
// Password validate
if (!user.password) {
error.password = 'Please provide a password'
} else if (user.password.length < 6) {
error.password = 'Password Must be greater or Equal to 6 characters'
}
return {
error,
isValid: Object.keys(error).length === 0
}
}
module.exports = validate
Thanks.
You don't need to put res.end() because when you called res.json() earlier, it already sent the response.
Please be advised that you should return when you call res.end(), res.send(), 'res.json()' and other operations that send the response, just like what you did with res.status(400).json(logValidate.error)
This should be one of the ways prevent you from getting ERR_HTTP_HEADERS_SENT, but keep in mind that if you have nested callbacks, you should return from the outer scope as well

Loopback 4 - POST request dtasource template

I am having issue to declare POST operation in Loopback 4 datasource file.
My template is as follows:
{
"template": {
"method": "POST",
"url": "https://reqres.in/api/login"
},
"functions": {
"login": []
}
}
My service interface
login(email: string, password: string): Promise<any>;
My Controller
#post('/loginTest')
async testingLogin(
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(TestModel, {
title: 'Post',
}),
},
},
})
testModel: TestModel, )
: Promise<any> {
// TEST MODEL CONTAIN JSON OBJECT {email: "" , password: ""}
console.log("Test Model Representation: ", testModel)
try {
var response = await this.loginService.login(testModel.email, testModel.password);
} catch (error) {
console.log("error", error)
}
console.log("Fake POST response", response)
return response;
};
I am using this fake API : https://reqres.in/api/login
I am getting following error:
Test Model Representation: { email: 'string', password: 'string' }
error Error: {"error":"Missing email or username"}
at callback (D:\loginApp\node_modules\loopback-connector-rest\lib\rest-builder.js:541:21)
at D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:269:22
at doNotify (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:157:49)
at RestConnector.ObserverMixin._notifyBaseObservers (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:180:5) {
statusCode: 400,
message: '{"error":"Missing email or username"}'
}
Fake POST response undefined
It look like my email and password is not passed ? Thanks for any help.
The login function you defined in the datasource file should match with the service interface. That means it would be something like:
"functions": {
"login": ["email", "password"]
}