I want transfer data js to node.js - javascript

I don't know how to transfer data from JavaScript to Node.js.
I need to POST the allUsers array and the user.username property.
var allUsers = []
var user = {
username: '',
password: ''
}
var background = document.getElementById("bg")
function verify() {
background.style.display = "inline"
var usrname = document.getElementById("username").value
var pswrd = document.getElementById("password").value
user.username = usrname
user.password = pswrd
axios.get("dbid").then((response) => {
var data = response.data
for (let key in data) {
var body = data[key]
allUsers.push(body.user.username)
}
return verified();
})
}
function verified() {
var inc = allUsers.includes(user.username)
if (user.password.length < 8) {
alert('Şifreniz en az 8 karakter olmalıdır!');
return background.style.display = "none";
} else if (inc) {
alert("Böyle bir mail adresi önceden kaydolmuş! Lütfen başka bir mail adresi deneyim.");
return background.style.display = "none";
} else {
alert("Başarılı, G-mail adresinize bir doğrulama kodu gönderildi...");
axios.post("dbid", {
user: user
})
return background.style.display = "none";
}
}

If you need to post an array of data (in this case allUsers) and a string (username) you need to use the JSON.stringify method to convert the array to a JSON string.
Here is an async function that will post the data you need to send to the server:
const postData = async () => {
try {
await axios.post(<url-to-post>, {
users: JSON.stringify(allUsers),
username: user.username
})
} catch (err) {
// Error posting data
console.log(err)
}
}

Related

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.');
}
};

2 Jquery ajax post requests. 2nd one gives error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I have one GET request at first to retrieve a data structure. Then I perform some changes and perform a PUT request to send the data structure to the server and update the record. When I click the submit button on the on the first form it works as expected and when I submit the second one it executes as expected, but it logs 2 errors. Furthermore, when I make 2 edits successively it crashes the app and gives an RangeError: Maximum call stack size exceeded error. The code related to the RangeError: Maximum call stack size exceeded error is at the bottom.
Image showing initial errors on update
Range Error Console Log
Here is my client side script:
<script>
const capitalize = ([first, ...rest]) =>
${first.toUpperCase()}${rest.join('')};
let patientDataRetrieved = false;
let _xhr,_xhr2 = null;
let patientID ;
let first_name;
let last_name;
let email;
let sex;
let date_of_birth;
let patient_phone;
let marital_status;
let emergency_contact1_rel ;
let emergency_contact1_phone;
let emergency_contact2_rel ;
let emergency_contact2_phone;
let spouse_phone;
$("body").on("contextmenu",function(e){
return false;
});
$('body').bind('cut copy ', function (e) {
e.preventDefault();
});
document
.getElementById("search")
.addEventListener("submit",ev => {
ev.preventDefault();
patientID = ev.target.patientID.value;
let uid = patientID;
getPatientDetails()
function getPatientDetails(){
if(_xhr2!= null)
_xhr2.abort();
if(patientDataRetrieved===false){
$(document).ready(()=>{
_xhr = $.ajax({
url: '/profile/'+uid,
type: 'GET',
cache: false,
success: function(data){
//Instantiate Variables of User Data
let userdata = data;
console.log(userdata);
first_name = userdata.first_name;
last_name = userdata.last_name;
sex = userdata.sex;
email = userdata.email;
let blood_type = userdata.blood_type;
date_of_birth = userdata.date_of_birth;
spouse_phone = userdata.spouse_phone;
patient_phone = userdata.patient_phone;
marital_status =userdata.marital_status;
spouse_phone = userdata.spouse_phone;
emergency_contact1_rel = userdata.emergency.contact1.relationship;
emergency_contact1_phone = userdata.emergency.contact1.phone;
emergency_contact2_rel = userdata.emergency.contact2.relationship;
emergency_contact2_phone = userdata.emergency.contact2.phone;
let chronic_illnesses = userdata.chronic_illnesses;
let past_surgeries = userdata.past_surgeries;
let allergies = userdata.allergies;
let long_term_medication = userdata.long_term_medication;
//Append User Data to respective td in table
$(".firstname").append(capitalize(first_name));
$(".lastname").append(capitalize(last_name));
$("#blood_type").val(blood_type);
$(".sex").append(capitalize(sex));
$(".date_of_birth").append(date_of_birth);
$(".patient_phone").append(patient_phone);
$(".marital_status").append(capitalize(marital_status));
$(".spouse_phone").append(spouse_phone);
$(".emergency_contact1_rel").append(capitalize(emergency_contact1_rel));
$(".emergency_contact1_rel").append(", Phone: "+emergency_contact1_phone);
$(".emergency_contact2_rel").append(capitalize(emergency_contact2_rel));
$(".emergency_contact2_rel").append(", Phone: "+emergency_contact2_phone);
$("#chronic_illnesses").val(chronic_illnesses);
$("#past_surgeries").val(past_surgeries);
$("#allergies").val(allergies);
$("#long_term_medication").val(long_term_medication);
document.getElementById("patientData").style.display ="block";
patientDataRetrieved = true;
return true;
}
, error: function(jqXHR, textStatus, err){
alert('text status '+textStatus+', err
'+err)
}
});
});
}
}
});
document.getElementById("editForm").addEventListener("submit", ev =>{
ev.preventDefault();
updatePatientInfo()
function updatePatientInfo() {
if(_xhr!=null){_xhr.abort()}
let formData = {
first_name: first_name,
last_name: last_name,
email: email,
blood_type: $("#blood_type").val(),
sex: sex,
date_of_birth:date_of_birth,
patient_phone:patient_phone,
marital_status:marital_status,
spouse_phone: spouse_phone,
emergency_contact1_relationship:emergency_contact1_rel,
emergency_contact1_phone:emergency_contact1_phone,
emergency_contact2_relationship:emergency_contact2_rel,
emergency_contact2_phone: emergency_contact2_phone,
chronic_illnesses: $("#chronic_illnesses").val(),
past_surgeries: $("#past_surgeries").val(),
allergies: $("#allergies").val(),
long_term_medication: $("#long_term_medication").val(),
uid: patientID,
};
_xhr2 = $.ajax({
url: "/edit_record_process",
type: "PUT",
data: formData,
datatype:"text",
encoded:true,
cache: false,
success:function(data){
if(data){
window.location.reload()
}
},
error: (err)=>{
alert(err);
}
});
}
});
Here's the server side code:
app.get("/profile/:uid", function (req, res){
//const current_user =
//const current_user =
const uid = req.params.uid;
db.ref("user_file_ref").on("value", snapshot=>{
snapshot.forEach( dataSnapshot=>{
if(uid === dataSnapshot.val().user_id){
//line referenced in range error
getFileFromNet(dataSnapshot.val().ipfs_ref).then( result =>
{
const hash = JSON.parse(result);
let decrypted_string = decrypt(hash);
let return_data = JSON.parse(decrypted_string);
return res.send(return_data);
}).catch((err) =>{
return console.log(err);
});
}else{
}
})
})
return true;
});
app.put("/edit_record_process", (req,res)=>{
let first_name = req.body.first_name;
let last_name= req.body.last_name;
let blood_type = req.body.blood_type ;
let sex = req.body.sex ;
let date_of_birth= req.body.date_of_birth ;
let email = req.body.email ;
let patient_phone= req.body.patient_phone ;
let userID = req.body.uid;
let marital_status= req.body.marital_status ;
let emergency= {
contact1:
{
"relationship":req.body.emergency_contact1_relationship,
"phone": req.body.emergency_contact1_phone
},
contact2:
{
"relationship":req.body.emergency_contact2_relationship,
"phone": req.body.emergency_contact2_phone
}
};
let chronic_illnesses = req.body.chronic_illnesses ;
let past_surgeries = req.body.past_surgeries ;
let allergies = req.body.allergies ;
let long_term_medication = req.body.long_term_medication ;
const userdata = {
"first_name" : first_name,
"last_name" : last_name,
"sex": sex,
"blood_type": blood_type,
"date_of_birth":date_of_birth,
"email":email,
"patient_phone": patient_phone,
"marital_status": marital_status,
"emergency": emergency,
"chronic_illnesses": chronic_illnesses,
"past_surgeries":past_surgeries,
"allergies": allergies,
"long_term_medication": long_term_medication,
}
let userdata_string = JSON.stringify(userdata);
let encrypted_user_data = JSON.stringify(encrypt(userdata_string));
sendFileToNet(encrypted_user_data).then((ipfs_object)=>{
let ipfs_path = ipfs_object.path;
db.ref("user_file_ref").on("value", snapshot=>{
snapshot.forEach(dataSnapshot => {
if(userID === dataSnapshot.val().user_id){
dataSnapshot.ref.update({ipfs_ref:ipfs_path}).then(()=>
{
return res.sendStatus(201);
}).catch((err)=>{
console.log(err)
})
}
})
})
});
});
IPFS API code:
const sendFileToNet = async (file_data) => {
const cid = function (data) {
return client.add(data).then(cid =>{return cid;}).catch(err=>{
console.log(err)})
}
const real_cid = await cid(file_data);
return real_cid;
}
const getFileFromNet = async (cid) =>{
const stream = client.cat(cid)
let data = ''
for await (const chunk of stream) {
// chunks of data are returned as a Buffer, convert it back to a
string
data += chunk.toString()
}
return data;
}

How to create user specific data when user logs in for the first time in realtime firebase database?

I want the code to behave such that it creates specific data when user is signed in but doesn't create it if already present in the firebase real-time database.
I have used the following code through which i check if the child is already present or not and if not then creates the child in firebase database, but somehow the code isn't behaving as it should.
Whenev the user logins again the complete data part is rewritten.
Snippet I need help in
if (!(checkdata(user.uid))) {
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
}
var database = firebase.database();
function checkdata(userid){
var ref = firebase.database().ref("users");
ref.once("value")
.then(function(snapshot) {
var datapresent = snapshot.hasChild(userid); // true
return datapresent
});
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl,
cropdata : []
});
}
Complete JS file
const signInBtn = document.getElementById('signinbtn');
const signOutBtn = document.getElementById('signoutbtn');
const userDetails = document.getElementById('username');
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
signInBtn.onclick = () => auth.signInWithPopup(provider);
signOutBtn.onclick = () => auth.signOut();
function toggle(className, displayState){
var elements = document.getElementsByClassName(className)
for (var i = 0; i < elements.length; i++){
elements[i].style.display = displayState;
}
}
auth.onAuthStateChanged(function(user) {
if (user) {
// signed in
toggle('userishere', 'block');
toggle('usernothere', 'none');
//userDetails.innerHTML = `<h3>Hello ${user.displayName}!</h3> <p>User ID: ${user.uid}</p>`;
userDetails.innerHTML = `Hello ${user.displayName}!`
console.log(user)
if (!(checkdata(user.uid))) {
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
}
} else {
// not signed in
toggle('userishere', 'none');
toggle('usernothere', 'block');
userDetails.innerHTML = '';
}
});
var database = firebase.database();
function checkdata(userid){
var ref = firebase.database().ref("users");
ref.once("value")
.then(function(snapshot) {
var datapresent = snapshot.hasChild(userid); // true
return datapresent
});
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl,
cropdata : []
});
}
I just found the solution, the asynchronous code wasn't waiting for my firebase response and just checeked if datapresent was true or not, so with a async definition before function and await before ref.once(value) does the trick and my problem is solve. Working code below :
const signInBtn = document.getElementById('signinbtn');
const signOutBtn = document.getElementById('signoutbtn');
const userDetails = document.getElementById('username');
var database = firebase.database();
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
signInBtn.onclick = () => auth.signInWithPopup(provider);
signOutBtn.onclick = () => auth.signOut();
async function checkdata(user){
let ref = firebase.database().ref("users");
let snapshot = await ref.once('value');
if (!snapshot.hasChild(user.uid)){
console.log(user)
writeUserData(user.uid,user.displayName,user.email,user.photoURL)
console.log("write done")
}
else{
console.log("did not write")
}
}
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture: imageUrl,
cropdata: []
});
}
function toggle(className, displayState) {
var elements = document.getElementsByClassName(className)
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = displayState;
}
}
auth.onAuthStateChanged(function (user) {
if (user) {
// signed in
toggle('userishere', 'block');
toggle('usernothere', 'none');
//userDetails.innerHTML = `<h3>Hello ${user.displayName}!</h3> <p>User ID: ${user.uid}</p>`;
userDetails.innerHTML = `Hello ${user.displayName}!`
console.log(user)
checkdata(user)
}
else {
toggle('userishere', 'none');
toggle('usernothere', 'block');
userDetails.innerHTML = '';
}
})

How do i get this firebase data to use it outside the loop?

I have this script that runs through all the child items in my realtime database from firebase:
methods: {
submit: function() {
const gebruikersref = firebase.database().ref('Gebruikers/')
var self = this
gebruikersref.once('value', function(snapshot) {
const lid = self.lidnummer;
const voornaam = self.voornaam;
const achternaam = self.achternaam;
const email = self.email;
snapshot.forEach(function(childSnapshot) {
const data = childSnapshot.val()
});
if(lid == data.Lidnummer) {
console.log('err')
} else {
gebruikersref.push({
Voornaam: voornaam,
Achternaam: achternaam,
Email: email,
Lidnummer: lid
});
}
});
}
}
but how do i get const data = childSnapshot.val() outside the foreach loop so i can use it here:
if(lid == data.Lidnummer) {
console.log('err')
} else {
gebruikersref.push({
Voornaam: voornaam,
Achternaam: achternaam,
Email: email,
Lidnummer: lid
});
}
Otherwise the else method runs x times the number of children and will push my data (that only may be pushed once) x times the children
If I correctly understand your question, since the asynchronous push() method returns a ThenableReference, you can use Promise.all() as follows:
submit: function() {
const gebruikersref = firebase.database().ref('Gebruikers/')
var self = this
gebruikersref.once('value', function(snapshot) {
const lid = self.lidnummer;
const voornaam = self.voornaam;
const achternaam = self.achternaam;
const email = self.email;
const promises = [];
snapshot.forEach(function(childSnapshot) {
const data = childSnapshot.val()
if (lid == data.Lidnummer) {
console.log('err')
} else {
promises.push(gebruikersref.push({
Voornaam: voornaam,
Achternaam: achternaam,
Email: email,
Lidnummer: lid
})
);
}
});
Promise.all(promises);
});
}

Firebase push don't work inside value event

I have code like this:
var firebase = new Firebase('https://<MY_APP>.firebaseio.com');
var users = firebase.child('users');
var usersDefer = $.Deferred();
var userName;
if (window.localStorage) {
userName = localStorage.getItem('username');
if (!userName) {
function newUser(users) {
if (userName) return;
var newUserName = prompt('Enter Username:');
if (users.indexOf(newUserName) !== -1) {
alert('Username already taken');
newUser(users);
} else {
localStorage.setItem('username', newUserName);
userName = newUserName;
console.log('push');
// this push don't work
users.push({
name: newUserName
});
console.log('after');
}
}
usersDefer.then(newUser);
}
}
users.once('value', function(snapshot) {
var value = snapshot.val()
if (value) {
var users = Object.values(value).map(function(object) {
return object.name;
});
usersDefer.resolve(users);
} else {
usersDefer.resolve([]);
}
});
and
users.push({
name: newUserName
});
don't work unless I use developer console, anybody have a clue why?
UPDATE:
Same happen if I use this code without jQuery Deferred
users.once('value', function(snapshot) {
function newUser(users) {
if (userName) return;
var newUserName = prompt('Enter your username');
if (users.indexOf(newUserName) !== -1) {
alert('Username already taken');
newUser(users);
} else {
userName = newUserName;
if (window.localStorage) {
localStorage.setItem('username', newUserName);
}
console.log('push');
users.push({
name: userName
});
console.log('after');
}
}
var value = snapshot.val()
var users;
if (value) {
users = Object.values(value).map(function(object) {
return object.name;
});
} else {
users = [];
}
if (window.localStorage) {
userName = localStorage.getItem('username');
if (!userName) {
newUser(users);
}
} else {
newUser(users);
}
});
The problem was that I was using same variable users for firebase reference and list of users.

Categories

Resources