Login Form displays invalid credentials until the button is pressed twice - javascript

I have a react component "Signin.js", I have some login input fields in it, I am trying to create a login system using nodejs, expressjs and MySQL. To do this, I have created a post request, that sends the data of my input fields to nodejs backend where the data is passed into the database to check if the login credentials are correct or not. If the credentials are found in the database, the global variable auth in my backend "index.js" becomes true, I am sending that variable from nodejs to reactjs using a get request. if auth is true, I should get redirected to the next page other wise it says, login failed.
The problem is that when I enter the correct credentials, in the first 2 clicks, I get login failed, but in the 3rd click, it redirects me to the next page.
Here is my react component Signin.js
import React, {useState , useEffect} from 'react';
import Navbar from './Navbar';
import './signin.css';
import {Link} from 'react-router-dom';
import axios, { Axios } from 'axios';
function Signin()
{
const [userId, setUserId] = useState("");
const [password, setPassword] = useState("");
const [accessCode, setAccessCode] = useState("");
const [auth , setAuth] = useState(false);
const receiveauthentication = () => {
console.log("Calling authentication function");
axios.get("http://localhost:3001/api/get/signin2").then((response) => {
setAuth(response.data);
console.log(response.data);
if(auth === true)
{
console.log(response.data);
setAuth(false);
document.location.href = "http://localhost:3000/Dashhome";
}
else{
alert('Incorrect Login/Password');
}
})
};
const signInInfoSent = () => {
axios.post("http://localhost:3001/api/get/signin", {userId:userId, password:password}).then(() => {
console.log("Successfully Login");
}).then(receiveauthentication());
}
return(
<>
<Navbar/>
<div id="signUp">
<div id="form">
<label htmlFor = "userId">User ID</label>
<input type="textbox" id="userId" placeholder = "Username" onChange={(e) =>{
setUserId(e.target.value);
}}/>
<label htmlFor = "password">Password</label>
<input type="password" id="password" placeholder = "Password" onChange={(e) =>{
setPassword(e.target.value);
}}/>
<label htmlFor = "otp">Access Code</label>
<input type="textbox" id="otp" placeholder = "OTP" onChange={(e) =>{
setAccessCode(e.target.value);
}}/>
<button onClick={()=>{ signInInfoSent() }}>Sign in</button>
</div>
</div>
</>
);
}
export default Signin;
Here is my nodejs backend index.js
const express = require('express')
const app = express()
const mySql = require('mysql');
const cors = require('cors')
const bodyParser = require('body-parser')
const db = mySql.createPool({
host:"127.0.0.1",
user:"root",
password:"password",
database:"kotekdatabase"
})
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.json())
app.use(cors())
let auth;
var userIdG;
var trade_data = {};
app.post("/api/get/signin", (req,res)=>{
const userid = req.body.userId;
userIdG = userid;
const password = req.body.password;
const sqlSelect =
`SELECT * FROM signup WHERE userid = ? AND password = ?`;
db.query(sqlSelect,[userid , password], (err, result)=> {
//console.log(err);
if(result != null)
{
//res.send(result);
console.log("Successfully Login");
auth = true;
}
else
{
console.log("UnSuccessfully Login");
auth = false;
}
})
})
app.get("/api/get/retrieveStrategies" , (req , res)=>{
const q = 'SELECT * FROM strategy WHERE userid = ?';
db.query(q , [userIdG] , (err , result)=>{
if(err)
{
console.log(err);
}
else{
console.log(result[0]);
res.send(result);
}
});
})
app.get("/api/get/signin2", (req,res) =>{
console.log(auth);
res.send(auth);
auth = false;
})
var strategyG;
app.post("/api/get/strategy", (req,res)=>{
console.log("Strategy Name received\n");
const str = req.body.strategy;
strategyG = str;
console.log(strategyG);
})
var signupAuth = 0;
app.post("/api/insert", (req,res)=>{
const userid = req.body.userId;
const password = req.body.password;
const consumerKey = req.body.consumerKey;
const consumerSecret = req.body.consumerSecret;
const accessToken = req.body.accessToken;
const sqlInsert = "INSERT INTO signup (userid, password, consumerKey, consumerSecret, accessToken) VALUES (?,?,?,?,?);"
db.query(sqlInsert, [userid, password, consumerKey, consumerSecret, accessToken], (err, result)=> {
if(err){
console.log(err);
signupAuth = 0;
console.log(signupAuth);
}
else {
signupAuth = 1;
console.log(signupAuth);
}
})
})
app.post("/api/tradeinfo", (req,res)=>{
console.log("Inserting fo user Id,Strategy:", userIdG,strategyG);
const userid = userIdG;
const Sno = strategyG;
const indexName = req.body.indexName;
const Sprice = req.body.Sprice;
const SLP = req.body.SLP;
const PE = req.body.PE;
const Exitt = req.body.Exit;
const TType = req.body.TType;
const SL = req.body.SL;
const CE = req.body.CE;
const Entry = req.body.Entry;
const sqlInsert = "INSERT INTO strategy (userid, Sname, indexName, strikePrice, SLP, PE, Exitt, tradeType, SL, CE, Entry) VALUES (?,?,?,?,?,?,?,?,?,?,?);"
db.query(sqlInsert, [userid, Sno, indexName, Sprice, SLP, PE, Exitt, TType, SL, CE, Entry], (err, result)=> {
//console.log(err);
console.log(err);
})
})
app.post("/api/get/strategysent", (req,res)=>{
const userid = userIdG;
const Sno = strategyG;
const indexName = req.body.indexName;
const Sprice = req.body.Sprice;
const SLP = req.body.SLP;
const PE = req.body.PE;
const Exitt = req.body.Exit;
const TType = req.body.TType;
const SL = req.body.SL;
const CE = req.body.CE;
const Entry = req.body.Entry;
const sqlSelect =
`SELECT userid FROM signup WHERE userid = ${userid} AND password = ${password} AND consumerKey = ${consumerKey}`;
db.query(sqlSelect, (err, result)=> {
//console.log(err);
if(result != null)
{
//res.send(result);
console.log("Successfully Login");
auth = true;
}
else
{
console.log("UnSuccessfully Login");
auth = false;
}
})
})
app.post("/api/get/trade_data" , (req,res)=>{
res.send(req.body);
console.log(req.body);
trade_data = req.body;
})
app.get("/api/send/trade_data" , (req , res)=>{
res.send(trade_data);
} )
app.listen(3001, () => {
console.log("running on port 3001");
})

You have a floating promise, receiveauthentication is called too soon, you need to call it within the first .then handler.
Try this:
axios.post("http://localhost:3001/api/get/signin", {userId:userId, password:password}).then(() => {
console.log("Successfully Login");
receiveauthentication();
edit
you can merge the signin to remove extra axios request, i.e. return auth on the first request, and wrap state checking within useEffect, as it's a side effect:
server:
app.post("/api/get/signin", (req,res)=>{
const userid = req.body.userId;
userIdG = userid;
const password = req.body.password;
const sqlSelect =
`SELECT * FROM signup WHERE userid = ? AND password = ?`;
db.query(sqlSelect,[userid , password], (err, result)=> {
//console.log(err);
if(result != null)
{
//res.send(result);
console.log("Successfully Login");
auth = true;
}
else
{
console.log("UnSuccessfully Login");
auth = false;
}
res.send(auth);
})
})
client
// set 0 to skip on first render
const [auth, setAuth] = useState(0);
const signInInfoSent = () => {
axios.post("http://localhost:3001/api/get/signin", {
userId: userId,
password: password
}).then((response) => {
console.log("Successfully Login");
setAuth(response.data);
}).catch(err => console.error(err));
}
useEffect(() => {
console.log('check auth', auth);
if (auth === true) {
document.location.href = "http://localhost:3000/Dashhome";
} else if (auth === false) {
alert('Incorrect Login/Password');
}
}, [auth]);

Related

Proxy error: Could not proxy request /auth/register from localhost:3003 to http://127.0.0.1:8800/api/ (ECONNREFUSED)

I watched video tutorials on youtube. https://youtu.be/0aPLk2e2Z3g and I got problems and http://localhost:3003/auth/register 500 (Internal Server Error) problem I don't know if this is the same problem or not.
I'm trying to change the proxy localhost to 127.0.0.1
I think my problem is with registering past
I stuck with this problem for 5 hours.
this is my controller auth.js
import { db } from "../db.js";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
export const register = (req, res) => {
//CHECK EXISTING USER
const q = "SELECT * FROM users WHERE email = ? OR username = ?";
db.query(q, [req.body.email, req.body.username], (err, data) => {
if (err) return res.status(500).json(err);
if (data.length) return res.status(409).json("User already exists!");
//Hash the password and create a user
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync(req.body.password, salt);
const q = "INSERT INTO users(`username`,`email`,`password`) VALUES (?)";
const values = [req.body.username, req.body.email, hash];
db.query(q, [values], (err, data) => {
if (err) return res.status(500).json(err);
return res.status(200).json("User has been created.");
});
});
};
export const login = (req, res) => {
//CHECK USER
const q = "SELECT * FROM users WHERE username = ?";
db.query(q, [req.body.username], (err, data) => {
if (err) return res.status(550).json(err);
if (data.length === 0) return res.status(404).json("User not found!");
//Check password
const isPasswordCorrect = bcrypt.compareSync(
req.body.password,
data[0].password
);
if (!isPasswordCorrect)
return res.status(400).json("Wrong username or password!");
const token = jwt.sign({ id: data[0].id }, "jwtkey");
const { password, ...other } = data[0];
res
.cookie("access_token", token, {
httpOnly: true,
})
.status(200)
.json(other);
});
};
export const logout = (req, res) => {
res.clearCookie("access_token",{
sameSite:"none",
secure:true
}).status(200).json("User has been logged out.")
};
and register.jsx
import React from "react";
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
const Register = () => {
const [inputs, setInputs] = useState({
username: "",
email: "",
password: "",
});
const [err, setError] = useState(null);
const navigate = useNavigate();
const handleChange = (e) => {
setInputs((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
await axios.post(`/auth/register`, inputs);
navigate("/login");
} catch (err) {
setError(err.response.data);
}
};
return (
<div className="auth">
<h1>Register</h1>
<form>
<input
required
type="text"
placeholder="username"
name="username"
onChange={handleChange}
/>
<input
required
type="email"
placeholder="email"
name="email"
onChange={handleChange}
/>
<input
required
type="password"
placeholder="password"
name="password"
onChange={handleChange}
/>
<button onClick={handleSubmit}>Register</button>
{err && <p>{err}</p>}
<span>
Do you have an account? <Link to="/login">Login</Link>
</span>
</form>
</div>
);
};
export default Register;
my localhost
"proxy": "http://localhost:8800/api/"
I'm making a face Sign up and see if your data is saved. But it has this problem. I've tried checking both video clips and looking for solutions from other sources but still can't help.

Fetch request stuck on pending and then doesn't go through

I'm making a full stack Rick and Morty application. Characters on the screen and the user can login and click on them to add them to favorites and then click on them on the favorites page to delete them from the favorites page.
The application works but crashes after a few minutes saying that a fetch request didn't work. In network section of the developer tools, these requests to add or delete characters are coming up as (pending) and then coming up as failures like two minutes later. At the same time, the requests are working from the perspective of the application, meaning that if I add or delete characters as a user and then logout and log back in, the changes are still there. The register and login requests to the backend are working normally with statuses of 200 as well. What's happening here?
The backend:
const express = require('express');
const application = express();
const mongoose = require('mongoose');
application.use(express.json());
mongoose.connect('process.env.DATABASE_PASSWORD')
.then(console.log('Connected to database'));
const db = mongoose.connection;
const port = process.env.PORT || 8080;
application.post('/register', (request, response) => {
const username = request.body.username;
const password = request.body.password;
const favorites = [];
db.collection('data').insertOne({
username,
password,
favorites,
});
});
application.post('/login', async (request, response) => {
const username = request.body.username;
const password = request.body.password;
const findUser = await db.collection('data').findOne({
username,
password,
});
if (findUser) {
response.send({ message: 'Welcome, ' + username + "!", user: username, favorites: findUser.favorites });
} else {
response.send({ message: 'Login unsuccessful'});
}
});
application.post('/addFavorite', (request, response) => {
const userNow = request.body.username;
const favoritesHere = request.body.favoritesCopy;
console.log({userNow, favoritesHere});
db.collection('data').updateOne(
{ username: userNow },
{ $set: { favorites: favoritesHere }},
)
});
application.post('/deleteFavorite', (request, response) => {
const userNow = request.body.username;
const favoritesHere = request.body.theData;
db.collection('data').updateOne(
{ username: userNow },
{ $set: { favorites: favoritesHere }},
);
});
application.listen(port, () => {
console.log('Application listening');
});
The frontend fetch add request (the delete request is similar):
import React, { useState, useEffect } from 'react';
import logo from '../rickandmortylogo.png';
import { useSelector, useDispatch } from 'react-redux';
import { addFavorite } from '../index.js';
const Body = () => {
const [characters, setCharacters] = useState([]);
const [currentName, setCurrentName] = useState('Placeholder');
const [nameInput, setNameInput] = useState('');
const [locationInput, setLocationInput] = useState('');
const [loading, setLoading] = useState(true);
const favorites = useSelector(state => state.favoritesList);
const userNow = useSelector(state => state.currentUser);
const loggedIn = useSelector(state => state.loggedIn);
const dispatch = useDispatch();
useEffect(() => {
let isMounted = true;
let url = 'https://rickandmortyapi.com/api/character/';
let array = [];
const getData = async () => {
for (let i = 1; i < 4; i++) {
let response = await fetch(url);
let data = await response.json();
for (let j = 0; j < 20; j++) {
array.push(data.results[j]);
}
url = data.info.next;
}
if (isMounted) {
setCharacters(array);
setLoading(false);
}}
getData();
return () => {
isMounted = false;
}
}, []);
const readInput = (e) => {
setNameInput(e.target.value);
}
const readLocationInput = (e) => {
setLocationInput(e.target.value);
}
const addData = (a, b, c, d) => {
const array = [a, b, c, d];
const favoritesCopy = [...favorites];
favoritesCopy.push(array);
dispatch(addFavorite(array));
if (loggedIn === true) {
fetch('/addFavorite', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
favoritesCopy,
username: userNow,
}),
});
}
};
return (
<div className="pt-5">
<div className="text-center mt-5">
<img src={logo} className="img-fluid" />
</div>
<h2>Click on a character here to add them to your favorites. Choose "Check Favorites" in the menu bar to see your favorites and "Search Characters" to come back.</h2>
<div className="all">
<h4>Search by name:</h4>
<input onChange={readInput} />
<h4>Search by location:</h4>
<input onChange={readLocationInput} />
<br />
<div className="row m-1">
{loading ? 'Loading can take a few seconds. Your Rick and Morty experience will be ready soon!' : characters.filter((item) => {
if (nameInput == "") {
return item;
} else {
if (item.name.toLowerCase().includes(nameInput.toLowerCase())) {
return item;
}
}
}).filter((item) => {
if (locationInput == "") {
return item;
} else {
if (item.location.name.toLowerCase().includes(locationInput.toLowerCase())) {
return item;
}
}
}).map((item, id) => {
return (
<>
<div className="col-md-4 border border-dark rounded" id="square" onClick={() => addData(item.name, item.image, item.location.name, item.status)}>
<h2>{item.name}</h2>
<img src={item.image} className="border rounded" />
<h4>Location: {item.location.name}</h4>
<h4>Status: {item.status}</h4>
</div>
</>
)
})}
</div>
</div>
</div>
);
};
export default Body;
You never end the request. You don't send anything in the response and don't call response.end either, nor next. That's why your request never ends.
Here are some examples:
Success message with content
res.status(200).json({ success: true});
Success message without content
res.sendStatus(204);
Of course requests are pending, you never send anything on related actions:
Use res.send and send something, or at least in case of success, send a success status like:
204 for a no content success operation, like a DELETE for example.
201 for a POST operation creating a new resource.
5xx for errors

Have trouble with sending data to db. Unsuccess request

Trying to push register data to db but server returns error 500 (Internal Server Error), I am just training so dont know how to fix it here's my code. The browser that the problem is in query hook or route path but i cant find it
const express = require('express')
const config = require('config')
const mongoose = require('mongoose')
const app = express()
const PORT = config.get('port') || 5000
app.use(express.json({extended:true}))
app.use('/api/auth', require('./routes/auth.routes'))
async function start(){
try{
await mongoose.connect(config.get("mongoURL"),{
useNewUrlParser:true,
useUnifiedTopology:true,
useCreateIndex:true,
})
app.listen(PORT, () => console.log(`app has been started on port ${PORT}...`))
}catch(e){
console.log('server Error', e.message)
process.exit(1)
}
}
start()
this is my route (routes/auth.routes.js) Route should validate achieved data and save indo db. Validation working, but if i make real user it returns err 500
const {Router} = require('express')
const User = require('../models/User')
const bcrypt = require('bcryptjs')
const config = require('config')
const {check, validationResult} = require('express-validator')
const router = Router()
router.post(
'/register',
[
check('email', 'incorrect email').isEmail(),
check('password', 'min 6 symb')
.isLength({min:6})
],
async(req,res) => {
try{
const errors = validationResult(req)
if(!errors.isEmpty()){
return res.status(400).json({
errors:errors.array(),
message:'incorrect data'
})
}
const {email, password} = req.body
console.log(req)
const candidate = await User.findOne({email})
if(candidate){
return res.status(400).json({message:'Already exists'})
}
const hashedPassword = await bcrypt.hash(password, 12)
const user = new User({email, password: hashedPassword})
await user.save()
res.status(201).json({message:'created'})
} catch(e){
res.status(500).json({message:'something goes wrong try again'})
}
})
module.exports = router
config file maybe needs i dont know
{
"port":5000,
"jwtSecret":"secret",
"mongoUri":"mongourl/myFirstDatabase?retryWrites=true&w=majority"
}
hook that should push data to server
import {useCallback, useState} from 'react'
export const useHttp = () => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const request = useCallback( async(url,method = "GET", body=null, headers={}) => {
setLoading(true)
try{
if(body){
body = JSON.stringify(body)
headers['Content-Type'] = 'application/json'
}
const response = await fetch( url, {method, body,headers} )
const data = await response.json()
if(!response.ok){
throw new Error(data.message ||'something goes wrong')
}
setLoading(false)
return data
} catch (e) {
setLoading(false)
setError(e.message)
throw e
}
},[])
const clearError = useCallback(()=>setError(null),[])
return {loading, request, error, clearError}
}
and page where it all must works
import {useEffect, useState} from 'react'
import { useHttp } from '../hooks/http.hook'
import { useMessage } from '../hooks/message.hook'
const AuthPage = () => {
const {loading,error, request, clearError} = useHttp()
const [form, setForm] = useState({})
const message = useMessage()
const handleChange = (e) => {
setForm({...form, [e.target.name]:[e.target.value] })
}
useEffect(()=>{
message(error)
clearError()
}, [error])
const registerSubmit = async()=>{
try{
const data = await request('/api/auth/register', 'POST', {...form})
console.log('Data',data)
}catch(e) {
}
}
return(
<>
<div className="input-field ">
<input onChange={handleChange}name="email" placeholder="put email" id="email" type="text" />
<label htmlFor="email">Email</label>
</div>
<div className="input-field ">
<input onChange={handleChange} name="password"placeholder="put password" id="password" type="text" />
<label htmlFor="password">password</label>
</div>
<button onClick={registerSubmit} disabled={loading} className='btn black'>Register</button>
</>
)
}
Node server returns error
Error: Illegal arguments: object, number
[0] at _async (/Users/user/first-nodeapp/node_modules/bcryptjs/dist/bcrypt.js:214:46)
[0] at /Users/user/first-nodeapp/node_modules/bcryptjs/dist/bcrypt.js:223:17
[0] at new Promise (<anonymous>)
[0] at Object.bcrypt.hash (/Users/user/first-nodeapp/node_modules/bcryptjs/dist/bcrypt.js:222:20)
[0] at /Users/user/first-nodeapp/routes/auth.routes.js:33:45
[0] at processTicksAndRejections (internal/process/task_queues.js:93:5)

Unable to get variable from frontend to back end with Axios.put

I'm using react/express/SQL
I have a simple program where user can enter data, view data and update their data. inserting and getting data from my SQL database works fine, but when I try to update data from my database I get the following error.
Error when trying to update data
TypeError: Cannot read property 'userEvent' of undefined
index.js
const express = require('express'); // node js frontend/backend lib
const app = express()
const mysql = require('mysql'); // DB
const cors = require('cors') //By default requests from any other origins will be restricted by the browser. We have two differnet local hosts, so by default wont be able we req res data
//Setting up SQL, hide password properly
const db = mysql.createConnection({
host:'localhost',
user: 'root',
password: '*****',
database: 'calendardb',
});
app.use(cors());
app.use(express.json()); // turns data into json
// insert information in to DB
app.post('/send',(req,res) =>{
const userEvent = req.body.userEvent
db.query('INSERT INTO calevent (userEvent) VALUES (?)',
userEvent, (err,result) =>{
if(err){
console.log(err)
} else{
res.send("Data send to DB")
}
}
);
});
//Getting data from DB
app.get("/getData",(req, res) =>{
db.query("SELECT * FROM calevent", (err, result) => {
if(err){
console.log(err)
}else{
res.send(result)
}
});
});
//Update data
app.put('/update', (res,req) => {
//const newUserEvent = "test";
//const id = 325;
const newUserEvent = req.body.userEvent;
const id = req.body.id;
db.query("UPDATE calevent SET userEvent = ? WHERE id = ?", [newUserEvent, id],(err, result) => {
if(err){
console.log(err)
}else{
console.log(result)
}
});
});
app.listen(3001, () =>{
console.log('bonger');
});
The problem is that it is unable to get the variables from the front end and access it in the backend. if I uncomment the following: //const newUserEvent = "test"; //const id = 325; and use that as my hardcoded user input, everything works fine, I can update my database.
app.js
import React from 'react';
import { useState,useEffect } from "react";
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
import Axios from 'axios';
const CalendarApp = () => {
var [selectedDate, newDate] = useState(new Date());
const [event, newEvent] = useState("")
const [userEvent, setUserEvent] = useState("")
const [items, setItem] = useState([])
const [userEventList, setUserEventList] = useState([])
const [newUserEvent, setNewUserEvent] = useState("")
//Add event to DB
const addUserEvent = () => {
Axios.post("http://localhost:3001/send", {userEvent: userEvent,
}).then(() => {
console.log("Data sent to DB")
setUserEventList([...userEventList,{userEvent: userEvent,}])
});
};
//Gets data from DB
const getUserEvent = () =>{
Axios.get("http://localhost:3001/getData").then((response) => {
setUserEventList(response.data)
});
};
//Updates data chosen by user
const updateUserEvent = (id) => {
console.log(newUserEvent, id)
Axios.put('http://localhost:3001/update', {newUserEvent:newUserEvent, id: id}).then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
};
return(
<div id="eventList">
<h2>Event List</h2>
<div className="List">
{userEventList.map((val,key) => {
return (
<div>
Event: {val.userEvent}, Key: {val.id}
<div>
<input type="text" placeholder="Edit" onChange={(event) => {
setNewUserEvent(event.target.value)
}}/>
<button onClick={() => {updateUserEvent(val.id)}}>Update</button>
</div>
</div>
)
})}
</div>
</div>
)
the code console.log(newUserEvent, id) returns the correct updated user input and id number but for some reason when using axios.put it does not send it to the back end to be used there.

How to make api endpoint target user's localhost when deployed to Heroku

I have this api which works fine when running locally. But, once it is deployed to Heroku i get a error 503 which is because it tries to target localhost on Heroku's server and not the user's localhost. Is there a way to make this target the user's localhost instead?
The frontend is React. Here's the code in React that fetches this api every 5sec.
axiosFunc = () => {
const { user } = this.props.auth;
console.log(user);
axios.get(`api/avaya/${user.id}`).then((res) => console.log(res));
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.axiosFunc();
this.interval = setInterval(this.axiosFunc, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
and this is the API on the backend with express
const router = require("express").Router();
const xml2js = require("xml2js");
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
const axios = require("axios");
axios({
method: "post",
baseURL: `http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.username}`,
timeout: 2000,
})
.then((reg) => {
xml2js
.parseStringPromise(reg.data, { mergeAttrs: true })
.then((result) => {
if (result.RegisterClientResponse.ResponseCode[0] === "0") {
const clientId = result.RegisterClientResponse.ClientId[0];
user.avayaClientId = clientId;
user.save();
}
const clientId = user.avayaClientId;
axios({
method: "post",
url: `http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`,
}).then((notification) => {
xml2js
.parseStringPromise(notification.data, { mergeAttrs: true })
.then((result) => {
const notifType = [];
const notifDetails = [];
for (let i in result.NextNotificationResponse) {
notifType.push(i);
}
const arranged = {
NotificationType: notifType[1],
ResponseCode:
result.NextNotificationResponse[notifType[0]][0],
};
for (let i in result.NextNotificationResponse[
notifType[1]
][0]) {
notifDetails.push(i);
}
for (let i = 0; i < notifDetails.length; i++) {
arranged[[notifDetails[i]][0]] =
result.NextNotificationResponse[notifType[1]][0][
notifDetails[i]
][0];
}
for (let i in arranged) {
if ("Outbound" in arranged) {
arranged.CallType = "Outbound";
} else if ("Inbound" in arranged)
arranged.CallType = "Inbound";
else {
arranged.CallType = " ";
}
}
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
});
});
})
.catch((err) => res.status(503).json(err));
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
EDIT: I was able to fix thanks to #Molda
using fetch instead of axios doesn't result in cors error.
New frontend code
getLogs = async () => {
const { user } = this.props.auth;
const reg = await fetch(
`http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.id}`
);
let regData = await reg.text();
let regxml = new XMLParser().parseFromString(regData);
if (regxml.attributes.ResponseCode === "0") {
axios.post(`/api/avaya/register/${user.id}`, regxml);
console.log(regxml.attributes.ResponseCode);
}
let resp = await fetch(`/api/avaya/getid/${user.id}`);
let clientId = await resp.text();
let logs = await fetch(
`http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`
);
let data = await logs.text();
var xml = new XMLParser().parseFromString(data);
axios.post(`/api/avaya/getlogs/${user.id}`, xml);
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.getLogs();
this.interval = setInterval(this.getLogs, 5000);
}
New backend code:
const router = require("express").Router();
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/register/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const clientId = req.body.attributes.ClientId;
user.avayaClientId = clientId;
user.save();
});
router.route("/getid/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
res.send(user.avayaClientId);
});
router.route("/getlogs/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const arranged = {
NotificationType: req.body.children[0].name,
ResponseCode: req.body.attributes.ResponseCode,
CallType: " ",
};
for (let i in req.body.children[0].attributes) {
if (i === "Outbound") {
arranged.CallType = "Outbound";
}
if (i === "Inbound") {
arranged.CallType = "Inbound";
}
arranged[i] = req.body.children[0].attributes[i];
}
console.log(arranged);
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
I really don't get the part of (requesting with Axios in API)
Is this a third party API ?
But I suggest you to use (.env) which is a file in your root folder contains the development config like base URLs, expire tokens, API keys ... etc
and when you upload to Heroku you have to make a (.env) in Heroku app and but your config
Let's take an example
in my development mode, my .env looks like
app_url = localhost:4000
port = 4000
db = development_api
db_username = root
db_password =
db_engine = mysql2
in my production mode, my .env looks like
app_url = http://appsomething.heroku.com
port = 80
db = production_api
db_username = root
db_password = 3210LDWAK#AALKQ
db_engine = mysql2
and read more about how to use .ENV

Categories