Storing multiple array values in one key JSON - javascript

Problem:
Its a sign up a new user form with HTML.
Im supposed to store multiple arrays(containing "username: username, password: password, topScore: 0) in one JSON key ("user" key) all it does right now is that it stores only one array, if I enter another one it just overwrites the current.
// In HTML the function is called:
//<form name = "signup" onsubmit="registerNewUser()>
var user = [];
function registerNewUser() {
/** Get the value of username, password and repeat password **/
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var passwordRepeat = document.getElementById("passwordRepeat").value;
/** boolean variable to check if the username already exits **/
var usernameExists = false;
/** if statement to check if password and passwordRepeat match **/
if (password == passwordRepeat) {
/** For loop to scan through registered users to check if username is already in use **/
for(let i = 0; i < user.length; i++) {
if(user[i].name == username) {
usernameExists = true;
}
}
if (usernameExists) {
alert("This user name already exists.");
}
else {
/** Put array into users in JSON storage with username,password and score values **/
user.push( {name: username, password: password, topScore: 0} );
localStorage.setItem("user", JSON.stringify(user));
alert("New account successfully created!");
/** Set variable usernameExists to its original value **/
usernameExists = false;
}
}
else {
alert("Passwords do not match. Please try again.");
}
}

i used your code and added it to a fiddle. But instead of input fields, i used global variables and just set new values to those.
html:
<div id="userArray"></div>
<div id="localStorage"></div>
js:
var Username = 'Peter';
var Password = 'Parker';
var PasswordRepeat = 'Parker';
/** your function, but instead of input fields using my variables to set the respective variables inside the function **/
registerNewUser();
document.getElementById("userArray").innerHTML = JSON.stringify(user);
document.getElementById("localStorage").innerHTML = localStorage.getItem("user");
Username = 'Gwen';
Password = 'Stacy';
PasswordRepeat = 'Stacy';
registerNewUser();
document.getElementById("userArray").innerHTML = JSON.stringify(user);
document.getElementById("localStorage").innerHTML = localStorage.getItem("user");
registerNewUser();
It runs perfectly fine... beside the things that #HMR and #Shubham Jain mentioned.
you should rename your array to users, so that everybody knows it contains multiple users and not just one. And if you dont initialize users with the localStorage item, what point in storing them there anyway.
I think you are just testing something and thats why you store the passwords in the localStorage. Otherwise it would be better to store those sensitive informations in a backend application. And encrypt them.
I would have commented this, but since my reputation is below 50, i can't :-(

Got it fixed: 1. changed onsubmit="return registerNewUser(users)" 2. Put return false; inside else statement where user.push is used 3. Put return false; inside else statement after alert("Passwords do not match") Thank you guys!

Related

Checking for login credentials in HTML5 Storage

i'm building a quizz app , which asks me to : Add user authentication: allow users to log in, and save their login credentials to local storage (HTML5 browser storage). what i want to add is to check if the user name && password (together, because you can have the same username and not the same password and vice versa), so i can prompt a "Welcome back (name of the user)".
i spent 3 days trying to figure out which logic works , tried everything but every time i get a logic problem where things doesn't go the way it should be , here's the code :
var usersinfo = {
users : []
}
localStorage.setItem("users", JSON.stringify(usersinfo.users))
function registerInfo(){
var name = document.forms[0].username.value;
var pw = document.forms[0].pw.value;
if (name === "" || pw === "") {
alert ('please complete all the forms')
} else {
var adding = JSON.parse(localStorage.getItem("users"));
// logic that goes here : i tried everything , looping...etc
}
return false;
}
Note that the function is attached to a button , and everything works fine on the HTML , the problem is in login logic .
Untested, but try something like this:
const users = JSON.parse(localStorage.getItem("users"));
if (users.some((user) => {
return user.name === document.forms[0].username.value;
})) {
alert('Welcome back!');
}
Basically, we use some on the array to loop through and figure out if any of the elements have the same name as the one from your form. If they do, we immediately stop looping and return true. If not, we return false.
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
And, do take #AnilRedshift's advice and don't store usernames/passwords in localstorage...

How to style Validation checking before "save"

This is just a best practice question that I have run into and can't find the answer for. Any input is welcome! (Backed up responses with data/research would be amazing)
Example Save Button
When my save button is pressed, I want to do some validation, name (must be first and last), age (must be from 0 - 125), email (valid email address) and if these are all true, I want to "save" the user (to a db or wherever doesn't matter)
Right now my functions are set up
// Global error handler for example
var errors = {};
// Save Button Function
saveButton = function(dataModel) {
var valid = true;
valid = validateName(valid, dataModel.name);
valid = validateAge(valid, dataModel.age, 'extraParam');
valid = validateEmail(valid, dataModel.email, 'secondParam', 'thirdParam');
valid = (dataModel.red) ? validateRedUser(valid, dataModel) : valid;
if (valid) {
// Save user to database
}
else {
// alert to user an error has occured
// user errors object to respond with the errors
}
}
I feel like passing around the valid state to each sub validation function is not the best approach to a problem like this. It works, but can it be improved?
Edit: A sub-validation function would look something like:
validateName = function(valid, dataModel.name) {
if (!dataModel.name) {
valid = false;
// access global error handler to save error
errors.name = 'error in the name';
}
return valid;
}
Taking your sample function added the valid state condition check.
validateName = function(valid, dataModel.name) {
if (!dataModel.name && valid) {
valid = false;
// access global error handler to save error
errors.name = 'error in the name';
}
return valid;
}

Checking data in deep array with includes (Firebase retrieve data JS)

So I am new to the Firebase database and what I like about it is that I don't have to build a whole backend for just storing some simple data. What I am trying to do is pushing data to an array that I like to recieve from firebase. Then after that I would like to check if the email that was filled in, is included in the data from the firebase database. But because it's firebase and it has multiple arrays, objects etc I don't know how to check that. So the flow is: User fills in data, Applications makes a call to the firebase db and the Application is retrieving the current data from firebase. Then the Application will check if the data that is inputed is already there, and if so, will throw an alert that the data is already in the database. If not, the data will be submitted.
Also, I am wondering if this is the right way to retrieve data from the database:
Main.js
function writeUserData() {
var name = document.getElementById("name").value;
var email = document.getElementById("email").value;
firebase.database().ref('/aanmeldingen/').push({
username: name,
email: email,
});
var dbRef = firebase.database().ref().child('/aanmeldingen/');
dbRef.on('value', snapshot => {
const snap = snapshot.val();
const array = [];
array.push(snap);
console.log(array);
const res = array.includes(email);
console.log(res);
console.log(email);
});
}
Output in console
As you can see this returns multiple data. The include function will check on the submitted emailadress. This returns false even I had inputted "info#webpack.com". How can I check the right data object? It has to check all objects under "0" and return in the console if the submitted emailadress is already there.
I haven't tested it yet but i hope you get the idea. Also this is not the most efficient way to do this.
function ifEmailExist(arr,email){
var _t = 0;
for(var x in arr){
for(var y in arr[x]){
if(arr[x][y].email){
if(arr[x][y] === email){
_t++;
}
}
}
}
return _t;
}
Usage:
if(ifEmailExist(arr,"info#webpack.com") > 0){
//do stuff
}
You should use child_added instead of value. Whenever a new node is added in database, child_added will trigger and then you can take action on the data.
var dbRef = firebase.database().ref().child('aanmeldingen');
dbRef.on('child_added', snapshot => {
var username = snapshot.val().username;
var email = snapshot.val().email;
console.log(username);
console.log(email);
});

How to require the user's password when you want to update the user's information in the Firebase JSON tree?

I've got a form which is used to update a user's information, both in the Firebase JSON tree and the seperate database which holds the email + password combination for the users. Whenever you want to update either the email or password, you need to provide an email + password combination for it to work.
However, when you only want to update the JSON tree you can do it without a password. My form requires you to enter your current password before anything can happen, but if you type in the wrong password it will still update the display name of the user.
So my question is, is there a way that I can require the correct password before actually updating anything in the database?
The code in my controller:
//If the user has entered a new display name
if (sharedInfo.getUser().displayName !== $scope.user.displayName) {
var isNameChanged = userLogic.changeDisplayName($scope.user);
isNameChanged.then(function(isSuccessful) {
if (isSuccessful === true) {
$scope.isSuccessful = true;
}
else {
$scope.error = 'Update failed';
}
});
}
Function in my service:
changeDisplayName: function(user) {
//Get the user ID
var userData = sharedInfo.getAuthState();
return fbRef.getSyncedReference('users/' + userData.uid).$update({displayName: user.displayName}).then(function() {
return true;
}, function(error) {
return false;
});
}

looping the local storage

I want to loop the local storage for the password and username to check if correct and alert a message if or if not.
The code is working well, but I don't know where to write the "invalid username" message because the loop goes through every record, so the messages pops ups for every record check until it finds it.
What I want is to pop up the message when the search is done.
Here is my code:
$("#login").click(function(){
var username =$("#user").val();
var password =$("#pass").val();
var userCount = localStorage.getItem('userCount');
for (i=1;i<=userCount;i++) {
var user = JSON.parse(localStorage.getItem("user" + i));
if((user.username == username)||(user.password == password)){
alert("welcome "+username);
} else {
alert("Invalid Username");//this message keeps poping up on every record until username found
}
}
});
Put the loop inside a function.
Return true (or the user object) from that function if anything inside the loop matched.
Return false after the loop (which you'll only reach if nothing matches).
Handle your alert outside the function based on the return value of calling it.
Set a boolean variable to true when you find a match, and stop the loop using break. Otherwise, if the boolean is still false after the loop completes, no match was found.
$("#login").click(function(){
var username =$("#user").val();
var password =$("#pass").val();
var userCount = localStorage.getItem('userCount');
var foundOne = false;
for (i=1;i<=userCount;i++) {
var user = JSON.parse(localStorage.getItem("user" + i));
if((user.username == username)&&(user.password == password)){
foundOne = true;
break;
}
}
if(foundOne) {
alert("welcome "+username);
// other "welcome" code
} else {
alert("Invalid Username");
}
});
NB, you may want to use the && operator instead of || here:
(user.username == username)&&(user.password == password)
otherwise you may get a match for one user who has the same password as another.

Categories