Updating Local Storage - javascript

I have a struggle with updating Local Storage values. I have "users" array from which I want to update my Local Storage, buy many problems have occured durning implementation. Please see code below, and also take note its only learning so dont be scared I use local storage for stroing login and password.
class Register {
constructor({
inputLogin,
inputPassword
}) {
this.inputLogin = inputLogin;
this.inputPassword = inputPassword;
}
users = [];
add() {
const btn = document.querySelector('#register-form__submit');
btn.addEventListener('click', (e) => {
e.preventDefault();
const usersData = {
login: this.inputLogin.value,
password: this.inputPassword.value
}
if (localStorage.getItem('users')) {
// // I dont know what to do here, I want to get existing value from local Storage. Put them back to array users and then set local storage with this old an new value... But I've encountered a lot of problems like nested arrays, overlooping etc. Please tell me guys how you would've done it.
} else {
this.users.push(usersData);
localStorage.setItem('users', JSON.stringify(this.users));
}
})
}
}
EDIT: Working solution. I hope it helps sombeody who wants to practice and doesn't know databases yet.
class Register {
constructor() {
this.inputLogin = document.getElementById('login')
this.inputPassword = document.getElementById('password')
this.users = []
}
add() {
//checking if inputs are empty
if (this.inputLogin.value === '' || this.inputPassword.value === '') {
this.alert('Musisz wypełnić wszystkie pola')
} else {
//creating object with users data
let userData = {
login: this.inputLogin.value,
password: this.inputPassword.value,
}
if (window.localStorage.getItem('users')) {
//checking if there are any users in local storage
const existingData = JSON.parse(window.localStorage.getItem('users'));
//looping through those values and checking if there is already such an user with this login.
for (let i = 0; i < existingData.length; i++) {
if (existingData[i].login === userData.login) {
if (document.querySelector('.red-alert')) {
return;
} else {
this.alert("user already exists");
break;
}
} else {
//checking if this.users[] is empty(this happens after refreshing page or restarting browser of course
if (this.users.length === 0) {
existingData.map((obj) => {
return this.users.push(obj);
})
this.users.push(userData);
localStorage.setItem('users', JSON.stringify(this.users))
window.location.href = "index.html";
}
//checking if there is some data in this.users. That means page was not refreshed nor browser was restarted.
else if (this.users.length > 0) {
this.users.push(userData);
localStorage.setItem('users', JSON.stringify(this.users))
console.log(this.users);
window.location.href = "index.html";
}
}
}
}
else {
//success when there are no users at all in this.users[] and local storage is empty
this.users.push(userData);
localStorage.setItem('users', JSON.stringify(this.users))
window.location.href = "index.html";
}
}
alert(text) {
const par = document.createElement('p')
par.classList.add('red-alert');
par.textContent = text;
document.querySelector('.register-form').appendChild(par)
}
}

You need to first check for the existing key and then update the value of the local storage. Have added in line comments for better understanding
// ..rest of the code
// check if the local storage have any key by this na,e
const currStoredData = localStorage.getItem('users');
// if key esxist
if (currStoredData) {
// push the existing value of the key in the array
this.users.push(currStoredData);
// set the new user data in the local storage
localStorage.setItem(usersData)
} else {
this.users.push(usersData);
localStorage.setItem('users', JSON.stringify(this.users));
}
})

You could read the local storage only at the beginning and work with the object after.
Because the storage only saves strings, you need to parse the value as well.
class Register {
constructor({
inputLogin,
inputPassword
}) {
this.inputLogin = inputLogin;
this.inputPassword = inputPassword;
}
users = JSON.parse(localStorage.getItem('users')) || [];
add() {
const btn = document.querySelector('#register-form__submit');
btn.addEventListener('click', (e) => {
e.preventDefault();
const usersData = {
login: this.inputLogin.value,
password: this.inputPassword.value
}
this.users.push(usersData);
localStorage.setItem('users', JSON.stringify(this.users));
})
}
}

Related

Simple MSAL Login/Authentication in JavaScript

I'm trying to do a simple login to Azure AD using the MSAL for JavaScript v2.0 library. We want users to be able to authenticate into our site with their work Microsoft accounts. All I need to do is be able to authenticate/login the user via Microsoft, and if they can login via their work Microsoft account, then they're granted access to our site.
I'm using the Javascript library and have followed the code from the Github page and while the login prompt is coming up, afterwards I have no idea how to check if the user is signed in.
Here's the code I'm using, which is basically what's in the sample code from Github:
<script type="text/javascript" src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.min.js"></script>
<script type="text/javascript">
const msalConfig = {
auth: {
clientId: "[ClientID goes here]",
authority: "https://login.microsoftonline.com/[tenant ID]",
knownAuthorities: ["login.microsoftonline.com"],
protocolMode: "OIDC",
redirectUri: "[page on our site that doesn't have MSAL auth, listed in Azure Reply URLs]"
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case msal.LogLevel.Error:
console.error(message);
return;
case msal.LogLevel.Info:
console.info(message);
return;
case msal.LogLevel.Verbose:
console.debug(message);
return;
case msal.LogLevel.Warning:
console.warn(message);
return;
}
}
}
}
};
// Add here scopes for id token to be used at MS Identity Platform endpoints.
const loginRequest = {
scopes: ["User.Read"]
};
const silentRequest = {
scopes: ["openid", "profile", "User.Read"]
};
const ua = window.navigator.userAgent;
const msie = ua.indexOf("MSIE ");
const msie11 = ua.indexOf("Trident/");
const msedge = ua.indexOf("Edge/");
const isIE = msie > 0 || msie11 > 0;
const isEdge = msedge > 0;
let signInType;
let accountId = "";
let credType = "";
// Create the main myMSALObj instance
const myMSALObj = new msal.PublicClientApplication(msalConfig);
// Register Callbacks for Redirect flow
myMSALObj.handleRedirectPromise().then(handleResponse).catch((error) => {
console.log(error);
});
function handleResponse(resp) {
alert("beginning handleResponse");
if (resp !== null) {
accountId = resp.account.homeAccountId;
credType = resp.account.credentialType;
myMSALObj.setActiveAccount(resp.account);
alert("response not null (already auth), accountId: " + accountId + ", credType: " + credType);
}
else {
const currentAccounts = myMSALObj.getAllAccounts();
if (!currentAccounts || currentAccounts.length < 1) {
alert("currentAccounts null/empty, going to signIn");
signIn("loginRedirect");
//return;
}
else if (currentAccounts.length > 1) {
// add choose account code here
alert("currentAccounts has multiple");
}
else if (currentAccounts.length === 1) {
const activeAccount = currentAccounts[0];
myMSALObj.setActiveAccount(activeAccount);
accountId = activeAccount.homeAccountId;
credType = activeAccount.credentialType;
alert("currentAccounts == 1; accountId: " + accountId + ", credType: " + credType);
}
}
}
async function signIn(method) {
signInType = isIE ? "loginRedirect" : method;
if (signInType === "loginPopup") {
return myMSALObj.loginPopup(loginRequest).then(handleResponse).catch(function (error) {
console.log(error);
});
}
else if (signInType === "loginRedirect") {
return myMSALObj.loginRedirect(loginRequest);
}
}
function signOut() {
const logoutRequest = {
account: myMSALObj.getAccountByHomeId(accountId)
};
myMSALObj.logoutRedirect(logoutRequest);
}
async function getTokenPopup(request, account) {
request.account = account;
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
console.log("silent token acquisition fails.");
if (error instanceof msal.InteractionRequiredAuthError) {
console.log("acquiring token using popup");
return myMSALObj.acquireTokenPopup(request).catch(error => {
console.error(error);
});
}
else {
console.error(error);
}
});
}
// This function can be removed if you do not need to support IE
async function getTokenRedirect(request, account) {
request.account = account;
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
console.log("silent token acquisition fails.");
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
console.log("acquiring token using redirect");
myMSALObj.acquireTokenRedirect(request);
}
else {
console.error(error);
}
});
}
So what happens upon going to this page is I get the two alerts saying "beginning handleResponse" and then "currentAccounts null/empty, going to signIn."
Then I'm redirected to MS sign-in page which I do with my work MS account. This succeeds.
I'm then redirected to the site I have listed in Azure Reply URLs, another page on our site that isn't secure and has no Azure login code.
The problem is I have no idea where to check that the user is signed in. If I try and check immediately after the signIn("loginRedirect") call in the handleResponse() function on the first page, the code never gets hit apparently. If I try and check on the page I'm redirected to, by instantiating the MSAL object and calling getAllAccounts(), this returns null.
It seems maybe on the page I'm redirected to I could call the ssoSilent() function (seems like this can check if user is authenicated?), but this requires a username/AccountId parameter. Well I don't frickin know this if a user hasn't (possibly) been authenticated yet! I don't really understand that.
So I don't know. It's probably something stupid I'm doing but I'm a pretty basic JavaScript person and am pretty much a total noob with authenication stuff. Any help would be epic.

If/else condition with Realtime firebase value

I wanted to ask, is it possible to use if/else on firebae's realtime results, which is:
enter image description here
if (Recent === waktu) {
Hasil : "1";
} else {
Hasil : "0";
}
This is my failed code:
// Eksekusi Jadwal
var waktu_jadwal = firebase.database().ref();
return waktu_jadwal.on('value').then((snapshot)=>{
return snapshot.forEach(jadwal_waktu=>{
if (jadwal_waktu.child("waktu").val() === (jadwal_waktu.child("Recent").val()) {
waktu_jadwal.update ({
Keadaan: {
Hasil: 1
}
});
} else {
waktu_jadwal.update ({
Keadaan: {
Hasil: 0
}
});
}
return console.log("added");
})
})
You can use an if/else as you have, as this is a callback function and will run like any other part of your script. Just be aware that you are using .on() which is an active firebase listener, if you intend on getting the value once, there is .once().
I would be cautious of shadowing variable names
try a more relative name such as 'Key'
return snapshot.forEach(Key=>{
if (Key.child("waktu").val() === (Key.child("Recent").val()) {
waktu_jadwal.update ({
You can also convert the object from snapshot data to a son object with
const data = snapshot.toJSON();

Changing value inside of array in local storage

So, I have an array stored in local storage called "users", with the fields "email", "id", "img", "pass", "user" and "usertype".
I want to have a field in which the user can change his email, but I can't do it. I tried this but it didn't work:
let loggedID = JSON.parse(localStorage.getItem("loggedID"))
changeEmailLink.addEventListener('click', function () {
users = JSON.parse(localStorage.getItem("users"))
users[loggedID].email = document.getElementById('changeEmail').value
})
I think the only thing I'm missing is using "localstorage.setItem()" to apply the change, but I'm afraid I'll delete the user records I have stored already if I don't do it right.
Any help would be apreciated. Thanks!
P.S. I am sure the "loggedID" is working since I already used it multiple times on this project. Also no jquery please, only vanilla JS. :)
I figured it out!
changeEmailLink.addEventListener('click', function () {
users = JSON.parse(localStorage.getItem("users"))
let usersUpd = users
for (i = 0; i < users.length; i++) {
if (users[i].email == users[loggedID].email) {
usersUpd[i].email = document.getElementById('changeEmail').value
} else {
usersUpd[i] = users[i]
}
localStorage.setItem("users", JSON.stringify(usersUpd))
}
})
This is what I did and it works great.
All you need to do is use the setItem function to maintain the new state.
localStorage
function setEmail(email) {
let loggedID = JSON.parse(localStorage.getItem("loggedID"))
let users = JSON.parse(localStorage.getItem("users"))
let user = users[loggedID]
user.email = email;
localStorage.setItem("users", users)
}
changeEmailLink.addEventListener('click', function () {
setEmail(document.getElementById('changeEmail').value)
})

Storing value to indexedDB if it is not defined

I'm trying to check if there is a record of 'uid' in indexed db from a service worker. If it's not defined, I need to add a value to it.
This is my code, I already tried in some ways that I found around other questions and sites, but none worked.
function checkUid() {
console.log('checking uid...');
var request = indexedDB.open('db',1);
request.onsuccess = function(event) {
var db = event.target.result;
var store = db.createObjectStore('Users', {keyPath:"users"});
var transaction = event.target.transaction;
db.transaction( '' ).objectStore( '' ).get( 'uid' ).onsuccess =
function(uid)
{
if (uid) {
console.log('uid found!');
console.log(uid);
console.log('uid end');
} else {
console.log('not found!');
db.transaction( '' ).objectStore( '' ).set( 'uid', 'aaaaa' );
console.log('uid end');
}
}
}
How can I do this?
This code opens the database with the name example, creates the object store called users if needed, gets the object with the key x123 from that store, and creates the object if it doesn't already exist.
function checkUid() {
let openRequest = indexedDB.open("example")
openRequest.onupgradeneeded = () => {
console.log("update needed")
openRequest.result.createObjectStore("users")
}
openRequest.onsuccess = () => {
console.log("opened database")
let store = openRequest.result.transaction("users", "readwrite").objectStore("users")
let uid = "x123"
let getRequest = store.get(uid)
getRequest.onsuccess = () => {
let result = getRequest.result
if (result) {
console.log("found:", result)
} else {
console.log("not found")
store.add("aaaaa", uid)
}
}
}
}
Use put() instead of set(), it will update the entry, or create one if it doesn't exist.
https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/put

AngularJs localStorage delete element in loop

I do not know how can i delete element in localStorage loop
In save method i add element and check for it duplicate
explain please how can i delete element using for example only id or all values
My Factory
.factory('SaveDocuments', function() {
var documents = [];
save: function (id, name, link) {
if(documents.filter(function(a){return a.id==id}).length)
{ alert('conflict!'); }
else {
// add to it,
documents.push({id: id, name: name, link: link});
// then put it back.
localStorage.setItem('document', JSON.stringify(documents));
}
},
del: function(id, name, link) {
if(documents.filter(function(a){return a.id==id}).length) {
for (i = 0; i < localStorage.length; i++){
key = localStorage.key(i);
value = localStorage.getItem(key);
localStorage.removeItem(value);
console.log(value);
break;
}
}
else {
alert('conflict!');
}
}
}
MyController
.controller('PageSearchCtrl', function($scope, ConstSearch, SaveDocuments) {
$scope.saveDocument = function() {
//Create new project
$scope.document = [{"id": 1, "name": "new1", "link": "#/const"}];
SaveDocuments.save($scope.document[0].id,$scope.document[0].name,$scope.document[0].link);
};
$scope.deleteDocument = function () {
$scope.document = [{"id": 1, "name": "new1", "link": "#/const"}];
//Create new project
SaveDocuments.del($scope.document[0].id,$scope.document[0].name,$scope.document[0].link);
}
I recommend changing your service to something like the following:
.factory('SaveDocuments', function () {
var lsKey = 'document', // the key to store the docs in local storage under
documents = JSON.parse(localStorage.getItem(lsKey) || '[]'); // initialise from localStorage
function saveToLocalStorage() {
localStorage.setItem(lsKey, JSON.stringify(documents));
}
return {
save: function (id, name, link) {
if (documents.filter(function (a) {
return a.id == id;
}).length) {
alert('conflict!');
} else {
// add to it,
documents.push({
id: id,
name: name,
link: link
});
saveToLocalStorage();
}
},
del: function (id, name, link) {
// clear all if del() is called with no arguments or null for all args
if (!id && !name && !link) {
documents = [];
saveToLocalStorage();
return;
}
var initialLength = documents.length;
documents = documents.filter(function (doc) {
return (!id || doc.id !== id) && (!name || doc.name !== name) && (!link || doc.link !== link);
});
// if nothing was removed, show error
if (documents.length === initialLength) {
alert('conflict!');
} else {
saveToLocalStorage();
}
}
};
});
Note that I correctly initialised it from the local storage state when the application starts (so when you reload the page the data is there correctly), used a variable to hold the only key you use to store the data in local storage (to keep the code DRY), and fixed your del() method so it keeps ones which don't match the deletion criteria or deletes everything if no arguments passed in, then just overwrites the value in local storage with the updated state.
NB: You should test this, I did not do any testing to see if this works.

Categories