I am trying to connect the front end with the back end using Axios as the API connector
When I followed the documentation of the Axios it gives me this error. However, when I try to test it on Postman it works perfectly fine.
Backed code working perfectly fine on postman:
Postman
Entry registered on MongoDB Atlas:
MongoDB Atlas
Back-end:
App.js
const express = require("express");
const app = express();
require('dotenv').config();
const mongoose = require("mongoose");
app.use(express.json());
const port = 5000;
mongoose
.connect(process.env.MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("connected to database");
})
.catch((e) => console.log(e));
app.listen(port, () => {
console.log("Server started");
});
require("./userDetails");
const User = mongoose.model("UserInfo");
//Password handler
const bcrypt = require("bcrypt");
const { Router } = require("next/router");
app.post("/register", async (req, res) => {
const { name, email, password } = req.body;
if (name == "" || email == "" || password == "") {
res.json({
status: "Failed",
message: "Empty input fields!",
});
} else if (!/^[a-zA-Z ]*$/.test(name)) {
res.json({
status: "FAILED",
message: "Invalid name input",
});
} else if (!/^[w-.]+@([w-]+.)+[w-]{2,4}$/.test(email)) {
res.json({
status: "FAILED",
message: "Invalid email input",
});
} else if (password.length < 8) {
res.json({
status: "FAILED",
message: "Password must be at least 8 or more characters",
});
} else {
User.find({ email })
.then((result) => {
if (result.length) {
res.json({
status: "Failed",
message: "User with the provided email already exists!",
});
} else {
const saltRounds = 10;
bcrypt
.hash(password, saltRounds)
.then((hashedPassword) => {
const newUser = new User({
uname: name,
email,
password: hashedPassword,
});
newUser
.save()
.then((result) => {
res.json({
status: "Success",
message: "SignUp Succesfull",
data: result,
});
})
.catch((err) => {
res.json({
status: "Failed",
message: "An error occured while saving account!",
});
});
})
.catch((err) => {
res.json({
status: "Failed",
message: "An error occured while hashing password!",
});
});
}
})
.catch((err) => {
console.log(err);
res.json({
status: "FAILED",
message: "An error occurred while checking for existing user!",
});
});
}
});
app.post("/signin", async (req, res) => {
const { email, password } = req.body;
if (email == "" || password == "") {
res.json({
status: "Failed",
message: "Empty inputs",
});
} else {
User.find({ email })
.then((data) => {
if (data) {
const hashedPassword = data[0].password;
bcrypt
.compare(password, hashedPassword)
.then((result) => {
if (result) {
res.json({
status: "SUCCESS",
message: "Signin successful",
data: data,
});
} else {
res.json({
status: "FAILED",
message: "Invalid password entered!",
});
}
})
.catch((err) => {
res.json({
status: "FAILED",
message: "An error orccured while comparing the passords",
});
});
} else {
res.json({
status: "FAILED",
message: "Invalid inputs",
});
}
})
.catch((err) => {
res.json({
status: "Failed",
message: "An error occurred while checking for existing user!",
});
});
}
});
module.exports = app;
api/client.js
import axios from "axios";
export default axios.create({ baseURL: "http://localhost:5000" });
Front-end:
Login.js:
import React, { useState } from 'react';
import { StatusBar } from 'expo-status-bar';
// formik
import { Formik } from 'formik';
//icons
import { Octicons, Ionicons, Fontisto } from '@expo/vector-icons';
import {
StyledContainer,
InnerContainer,
PageLogo,
PageTitle,
SubTitle,
StyledFormArea,
LeftIcon,
StyledInputLabel,
StyledTextInput,
RightIcon,
StyledButton,
ButtonText,
Colors,
Line,
MsgBox,
ExtraView,
ExtraText,
TextLink,
TextLinkContent,
} from './../components/style';
import { View, ActivityIndicator } from 'react-native';
//colors
const { brand, darkLight, primary } = Colors;
//keyboard avoid view
import KeyboardAvoidingWrapper from '../components/KeyboardAvoidingWrapper';
// API client
import axios from 'axios';
const Login = ({ navigation }) => {
const [hidePassword, setHidePassword] = useState(true);
const [message, setMessage] = useState();
const [messageType, setMessageType] = useState();
const handleLogin = (credentials, setSubmitting) => {
handleMessage(null);
const url = 'http://localhost:5000/signin';
axios
.post(url, credentials)
.then((response) => {
const result = response.data;
const { message, status, data } = result;
if (status !== 'SUCCESS') {
handleMessage(message, status);
} else {
navigation.navigate('Welcome', { ...data[0] });
}
setSubmitting(false);
})
.catch((error) => {
console.log(error.JSON());
setSubmitting(false);
handleMessage('An error occurred. Check your network and try again');
});
};
const handleMessage = (message, type = 'FAILED') => {
setMessage(message);
setMessageType(type);
};
return (
<KeyboardAvoidingWrapper>
<StyledContainer>
<StatusBar style="dark" />
<InnerContainer>
<PageLogo resizeMode="cover" source={require('./../assets/Logo.png')} />
<PageTitle>Umbrellah</PageTitle>
<SubTitle>Account Login</SubTitle>
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values, { setSubmitting }) => {
if (values.email == '' || values.password == '') {
handleMessage('Please fill all the fields');
setSubmitting(false);
} else {
handleLogin(values, setSubmitting);
}
}}
>
{({ handleChange, handleBlur, handleSubmit, values, isSubmitting }) => (
<StyledFormArea>
<MyTextinput
label="Email Address"
icon="mail"
placeholder="[email protected]"
placeholderTextColor={darkLight}
onChangeText={handleChange('email')}
onBlur={handleBlur('email')}
value={values.email}
keyboardType="email-address"
/>
<MyTextinput
label="Password"
icon="lock"
placeholder="* * * * * * * * * * * * * *"
placeholderTextColor={darkLight}
onChangeText={handleChange('password')}
onBlur={handleBlur('password')}
value={values.password}
secureTextEntry={hidePassword}
isPassword={true}
hidePassword={hidePassword}
setHidePassword={setHidePassword}
/>
<MsgBox type={messageType}>{message}</MsgBox>
{!isSubmitting && (
<StyledButton onPress={handleSubmit}>
<ButtonText>Login</ButtonText>
</StyledButton>
)}
{isSubmitting && (
<StyledButton disabled={true}>
<ActivityIndicator size="large" color={primary} />
</StyledButton>
)}
<Line />
<StyledButton google={true} onPress={handleSubmit}>
<Fontisto name="google" color={primary} size={25} />
<ButtonText google={true}>Sign in with Google</ButtonText>
</StyledButton>
<ExtraView>
<ExtraText>Don't have an account already? </ExtraText>
<TextLink onPress={() => navigation.navigate('SignUp')}>
<TextLinkContent>Signup</TextLinkContent>
</TextLink>
</ExtraView>
</StyledFormArea>
)}
</Formik>
</InnerContainer>
</StyledContainer>
</KeyboardAvoidingWrapper>
);
};
const MyTextinput = ({ label, icon, isPassword, hidePassword, setHidePassword, ...props }) => {
return (
<View>
<LeftIcon>
<Octicons name={icon} size={30} color={brand} />
</LeftIcon>
<StyledInputLabel> {label} </StyledInputLabel>
<StyledTextInput {...props} />
{isPassword && (
<RightIcon onPress={() => setHidePassword(!hidePassword)}>
<Ionicons name={hidePassword ? 'md-eye-off' : 'md-eye'} size={30} color={darkLight} />
</RightIcon>
)}
</View>
);
};
export default Login;
api/client.js
import axios from 'axios';
export default axios.create({baseURL: 'http://localhost:5000'})
2
Answers
Hi guys I managed to find the solution for the issues.
First of all huge thanks to Mostafa for his answer.
https://axios-http.com/docs/handling_errors
Change JSON to toJSON:
Before:
After:
Change localhost to your IP Address:
Before:
After:
Each tool and library may have a different structure for response. If you’re using Axios you must follow the Axios structure.
The error is thrown from this part of the code, which you’re trying to use
error.JSON
:If you want to handle errors in Axios, then you need to read about it in their official documentation.
e.g: