How to replace data inside the localStorage - javascript

const newFirst = document.getElementById("changeFName");
const newLast = document.getElementById("changeLName");
const newMail = document.getElementById("changeMail");
const newPass = document.getElementById("changePass");
const saveMe = document.getElementById("btn-save");
newData = (e) => { //mouseclick
e.preventDefault();
const first_name = changeFName.value;
const last_name = changeLName.value;
const e_mail = changeMail.value;
const pass_word = changePass.value;
let user_data = {
newFirst: first_name,
newLast: last_name,
newMail: e_mail,
newPass: pass_word,
}
let clientsArr = JSON.parse(localStorage.getItem('users'));
clientsArr.push(user_data);
localStorage.setItem("users", JSON.stringify(clientsArr));
}
saveMe.addEventListener("click", newData);
I've been trying to replace stored data of user using my "signup form" inside the local storage but:
the data is not being replace it's just creating new user (name,lastname,email,password)
I recycled my signup code hoping that this will work,
I have also login form that allowing each user to store to do list without changing the to do list of each other.
this is a TO-DO-LIST project from online course.

You try use below code
Reference: enter link description herehttps://www.w3schools.com/jsref/prop_win_localstorage.asp
<!DOCTYPE html>
<html>
<head>
<script>
function clickCounter() {
if(typeof(Storage) !== "undefined") {
if (localStorage.clickcount) {
localStorage.clickcount = 2;
localStorage.clickcount = Number(localStorage.clickcount)+1;
} else {
localStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = "You have clicked the button " + localStorage.clickcount + " time(s).";
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support web storage...";
}
}
</script>
</head>
<body>
<p><button onclick="clickCounter()" type="button">Click me!</button></p>
<div id="result"></div>
<p>Click the button to see the counter increase.</p>
<p>Close the browser tab (or window), and try again, and the counter will continue to count (is not reset).</p>
</body>
</html>

you need a unique field to recognize user like id, email.
using this code you can update your existing user data (without email)
const newEmail = document.getElementById("email");
const newName = document.getElementById("name");
const frm = document.getElementById("frm");
frm.addEventListener("submit", e => {
e.preventDefault();
const email = newEmail.value;
const name = newName.value;
const userData = { email, name };
const storage = JSON.parse(localStorage.getItem("users"));
if (!storage) {
localStorage.setItem("users", JSON.stringify([userData]));
} else {
const userIndex = storage.findIndex(el => el.email === email);
if (userIndex>=0) {
storage[userIndex] = userData;
localStorage.setItem("users", JSON.stringify(storage));
} else {
storage.push(userData);
localStorage.setItem("users", JSON.stringify(storage));
}
}
});
<form id="frm">
email: <input id="email" type="text" />
name: <input id="name" type="text" />
<button type="submit">save me</button>
</form>

Related

javascript - localStorage - issue with a loop and message to display

In the script below, I try to record in the bowser the name of the users who connect to my application. If it is the first time that a user connects, when he presses the "submit" button to connect to the application I want a message "Welcome" + name + "!
If the user has already connected (his name is already registered in the localStorage), when he presses the submit button, I want a "Welcome back" + name + "!
Thank you for the comments below, I tried to take them into account. When I run the updated code below, only welcome appear on the message. The name of the user is not included on the message. How can I modify my code to correct this problem?
Thank you in advance for your advice.
JS script:
let myButton = document.getElementById ("myButton");
let myText = document.getElementById ("username");
function store() {
let n = 0;
while (localStorage.getItem("username" + n)) {
n++;
}
localStorage.setItem("username" + n, myText.value);
}
function welcomeUsername(){
let resultMessage = "Welcome "
let n = 0;
while (n) {
let user = localStorage.getItem("username" + n);
if(myText.value != user){
resultMessage += myText.value + "!";
break;
} else {
resultMessage += "back" + myText.value + "!";n++;
}
}
alert(resultMessage);
}
HTML Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<br />
<br />
<div class ="login_card"></div>
<div class = "log_head">
<h1>Login</h1>
</div>
<div class = "log_body">
<br />
<label for="uname"><b>Please enter your username below and click on submit:</b></label> <br>
<input type="text" value = "Enter username" onfocus = 'this.value =""' id = "username"> <br>
<br> <br>
<input type="button" onClick="welcomeUsername();location.href ='/index';" value = "Submit" id = "myButton">
</div>
</div>
this part of your code has problem let value = localStorage.getItem("username"). you cant get any value from your localstorage since you set them 'username'+n, that;s why your if statement always run.
can you try this: while (n) {let user = localStorage.getItem("username" + n); if (myText.value == user) {resultMessage += myText.value; break; } else {resultMessage += "back" + myText.value + "!"; n++; }}
Try this.
const btn = document.getElementById('myButton');
// get a welcome message
const welcomeText = (name) => {
// store the name as an array type, initialize if it does not exist
let names = localStorage.getItem('usernames');
names = names == null ? [] : names;
// check if the name exists and decide the welcome message according to the result
if (names.includes(name)) {
return `Welcome back ${name}`;
} else {
// update storage information
names.push(name);
localStorage.setItem('usernames', names);
return `Welcome ${name}`;
}
};
// send name and call method
const submit = () => {
const name = document.getElementById('username').value;
alert(welcomeText(name));
};
btn.addEventListener('click', submit);

jinja2.exceptions.UndefinedError: 'participant' is undefined

I'm trying to build a video chat webapp using Twilio following https://www.twilio.com/blog/build-video-chat-application-python-javascript-twilio-programmable-video, but I keep getting the error listed in the title. From what I've gathered, I'm trying to call upon the attributes of an object (sid, name) that was never really defined (participant), but I'm not sure where in my code to define it.
<body>
<h1>join existing jam</h1>
<form>
<label for="username">Name: </label>
<input type="text" name="username" id="username">
<button id="join_leave">join</button>
</form>
<p id="count"></p>
<div id="container" class="container">
<div id="local" class="participant"><div></div><div>Me</div></div>
<div id="{{ participant.sid }}" class="participant">
<div></div> <!-- the video and audio tracks will be attached to this div -->
<div>{{participant.name}}</div>
</div>
</div>
<script src="//media.twiliocdn.com/sdk/js/video/releases/2.3.0/twilio-video.min.js"></script>
<script>
let connected=false;
const usernameInput = document.getElementById('username');
const button = document.getElementById('join_leave');
const container = document.getElementById('container');
const count = document.getElementById('count');
let room;
function addLocalVideo() {
Twilio.Video.createLocalVideoTrack().then(track => {
let video = document.getElementById('local').firstChild;
video.appendChild(track.attach());
});
};
function connectButtonHandler(event) {
event.preventDefault();
if (!connected) {
let username = usernameInput.value;
if (!username) {
alert('Enter your name before connecting');
return;
}
button.disabled = true;
button.innerHTML = 'connecting...';
connect(username).then(() => {
button.innerHTML = 'leave';
button.disabled = false;
}).catch(() => {
alert('Connection failed. Is the backend running?');
button.innerHTML = 'join';
button.disabled = false;
});
}
else {
disconnect();
button.innerHTML = 'join';
connected = false;
}
};
function connect(username) {
let promise = new Promise((resolve, reject) => {
// get a token from the back end
fetch('/login', {
method: 'POST',
body: JSON.stringify({'username': username})
}).then(res => res.json()).then(data => {
// join video call
return Twilio.Video.connect(data.token);
}).then(_room => {
room = _room;
room.participants.forEach(participantConnected);
room.on('participantConnected', participantConnected);
room.on('participantDisconnected', participantDisconnected);
connected = true;
updateParticipantCount();
resolve();
}).catch(() => {
reject();
});
});
return promise;
};
function updateParticipantCount() {
if (!connected)
count.innerHTML = 'Disconnected.';
else
count.innerHTML = (room.participants.size + 1) + ' participants online.';
};
function participantConnected(participant) {
let participantDiv = document.createElement('div');
participantDiv.setAttribute('id', participant.sid);
participantDiv.setAttribute('class', 'participant');
let tracksDiv = document.createElement('div');
participantDiv.appendChild(tracksDiv);
let labelDiv = document.createElement('div');
labelDiv.innerHTML = participant.identity;
participantDiv.appendChild(labelDiv);
container.appendChild(participantDiv);
participant.tracks.forEach(publication => {
if (publication.isSubscribed)
trackSubscribed(tracksDiv, publication.track);
});
participant.on('trackSubscribed', track => trackSubscribed(tracksDiv, track));
participant.on('trackUnsubscribed', trackUnsubscribed);
updateParticipantCount();
};
function participantDisconnected(participant) {
document.getElementById(participant.sid).remove();
updateParticipantCount();
};
function trackSubscribed(div, track) {
div.appendChild(track.attach());
};
function trackUnsubscribed(track) {
track.detach().forEach(element => element.remove());
};
function disconnect() {
room.disconnect();
while (container.lastChild.id != 'local')
container.removeChild(container.lastChild);
button.innerHTML = 'Join call';
connected = false;
updateParticipantCount();
};
addLocalVideo();
button.addEventListener('click', connectButtonHandler);
</script>
</body>
Also, if it helps, this is the app.py that I'm calling from terminal:
import os
from dotenv import load_dotenv
from flask import Flask, render_template, request, abort
from twilio.jwt.access_token.grants import VideoGrant
load_dotenv()
twilio_account_sid=os.environ.get("TWILIO_ACCOUNT_SID")
twilio_api_key_sid = os.environ.get('TWILIO_API_KEY_SID')
twilio_api_key_secret = os.environ.get('TWILIO_API_KEY_SECRET')
app=Flask(__name__)
#app.route('/')
def index():
return render_template('joinJam.html')
#app.route('/login',methods=['POST'])
def login():
username=request.get_json(force=True).get('username')
if not username:
abort(401)
token=AccessToken(twilio_account_sid, twilio_api_key_sid, twilio_api_key_secret, identity=username)
token.add_grant(VideoGrant(room='My Room'))
return {'token': token.to_jwt().decode()}
Twilio developer evangelist here.
Your issue is in the HTML here:
<div id="container" class="container">
<div id="local" class="participant"><div></div><div>Me</div></div>
<div id="{{ participant.sid }}" class="participant">
<div></div> <!-- the video and audio tracks will be attached to this div -->
<div>{{participant.name}}</div>
</div>
</div>
You are trying to refer to a participant object that does not exist.
In this case you are trying to render the participant information for the local participant. Instead of doing so directly in the HTML, you need to do this in the JavaScript once you have successfully requested the media of your local participant.
Your HTML should be:
<div id="container" class="container">
<div id="local" class="participant"><div></div><div>Me</div></div>
</div>
Then the showing of your media will be handled by the addLocalVideo method.

How to update JSON query / data after new user input?

I'm creating a weather dashboard that updates every 5 seconds. I would like the user to be able to change the target city, and have the dashboard update with the new data.
Problem is every time they input a new city, the previous data stays and it seems to be looping through all the inputs the user has made so far.
I would like the data to be updated after the user inputs a new city, rather than added. This is my code:
window.onload = function() {
const api_key = "c7eedc2fa8594d69aa6122025212904";
const inputCity = document.getElementById("inputCity");
const getCity = document.querySelector("form");
getCity.addEventListener("submit", e => {
// Prevent the form from submission
e.preventDefault();
var inputVal = inputCity.value;
var api_url = "http://api.weatherapi.com/v1/forecast.json?key=" + api_key + "&q=" + inputVal + "&days=3&aqi=no&alerts=no";
// Get the dataset
function refreshData() {
fetch(api_url).then(response => {
response.json().then(json => {
var dataset = json;
var output = formatResponse(dataset);
})
// Catch error - for example, the user doesn't input a valid city / postcode / country
.catch(error => console.log("not ok")); // TO BE IMPROVED
})
}
refreshData(); // Display the dashboard immediately
setInterval(refreshData, 5000); // And then refresh the dashboard every X milliseconds
});
function formatResponse(dataset) {
console.log(dataset);
// Current temp
var currentTemp = [dataset.current.temp_c];
console.log(currentTemp);
document.getElementById("currentTempDsp").innerHTML = currentTemp + "°";
// Current state icon
var currentIcon = [dataset.current.condition.icon];
console.log(currentIcon);
document.getElementById("iconDsp").src = "http://" + currentIcon;
// Current state text
var currentText = [dataset.current.condition.text];
console.log(currentText[0]);
document.getElementById("currentStateDsp").innerHTML = currentText;
}
}
<form id="getCity" class="search">
<label id="labelCity">Search for a city...</label></br>
<input type="text" id="inputCity" class="inputCity" placeholder="Type city name here...">
<button id="submitCity" type="submit" class="submitCity"><i class="fas fa-search"></i>Submit</button>
</form>
<div class="state">
<h2 id="currentTempDsp"></h2>
<img id="iconDsp"/>
<span id="currentStateDsp"></span>
</div>
</div>
</div>
When you create an interval using setInterval() it continues to execute until the page is reloaded, navigated away from, or explicitly cleared using clearInterval(). Simply setting more intervals will not stop any previous ones from firing.
Use a globally-scoped variable to store the return value of setInterval() - check if it's set in the beginning of your submit event handler and clear it if it is.
A simplified example of how you could get this done:
const locations = [{
temp: 73,
conditions: 'Sunny'
}, {
temp: 22,
conditions: 'Mostly Cloudy'
}];
var currentInterval = null;
const updateTemp = locationData => {
document.querySelector(".number").innerText = locationData.temp;
document.querySelector(".conditions").innerText = locationData.conditions;
console.log(`updated interface with temperature (${locationData.temp}) and conditions (${locationData.conditions}) data`);
}
[...document.querySelectorAll('.add-location')].forEach(button => {
button.addEventListener('click', (e) => {
// clear the interval
if (currentInterval) {
clearInterval(currentInterval);
currentInterval = null;
console.log('cleared currentInterval');
}
updateTemp(locations[parseInt(e.srcElement.dataset.loc)]);
currentInterval = setInterval(function () {
updateTemp(locations[parseInt(e.srcElement.dataset.loc)]);
}, 2500);
});
});
* {
font-family: sans-serif;
}
.temp {
font-size: 2em;
}
.conditions {
font-style: italic;
}
<div class="temp">
<span class="number">--</span>
<span class="deg">°</span>
</div>
<div class="conditions">--</div>
<div>
<button class="add-location" data-loc="0">Add location 0</button>
<button class="add-location" data-loc="1">Add location 1</button>
</div>

Storage and show multiple outputs

I have a simple text input where users type anything and after sumbitting text appear on a page and stays there, which I done with localStorage, but after refreshing the page only last typed input is showing, Ill post my code to be more specific:
HTML:
<body>
<input id="NewPostField" type="text" value="">
<button onclick="myFunction()">Post</button>
<div id="Posts"></div>
</body>
JavaScript:
function myFunction() {
var NewPostField =
document.getElementById("NewPostField");
var newPost = document.createElement("p");
localStorage.setItem('text',
NewPostField.value);
newPost.innerHTML = NewPostField.value;
var Posts = document.getElementById("Posts");
Posts.appendChild(newPost);
}
(function() {
const previousText = localStorage.getItem('text');
if (previousText) {
var NewPostField = document.getElementById("NewPostField");
NewPostField.value = previousText;
myFunction();
}
})();
Any help will be great!
It seems that your code is only storing the last value posted.
To store more than one post, one idea is to stringify an array of values to store in localStorage.
Then, parse that stringified value back into an array as needed.
Here's an example:
function getExistingPosts() {
// fetch existing data from localStorage
var existingPosts = localStorage.getItem('text');
try {
// try to parse it
existingPosts = JSON.parse(existingPosts);
} catch (e) {}
// return parsed data or an empty array
return existingPosts || [];
}
function displayPost(post) {
// display a post
var new_post = document.createElement("p");
new_post.innerHTML = post;
posts.appendChild(new_post);
}
function displayExistingPosts() {
// display all existing posts
var existingPosts = getExistingPosts();
posts.innerHTML = '';
inputPost.value = '';
if (existingPosts.length > 0) {
existingPosts.forEach(function(v) {
displayPost(v);
});
inputPost.value = existingPosts.slice(-1)[0];
}
}
function addPost(post) {
// add a post
var existing = getExistingPosts();
existing.push(post);
localStorage.setItem('text', JSON.stringify(existing));
displayPost(post);
}
function clearPosts() {
// clear all posts
localStorage.removeItem('text');
displayExistingPosts();
}
var posts = document.getElementById("posts");
var inputPost = document.getElementById("input_post");
var btnPost = document.getElementById('btn_post');
var btnClear = document.getElementById('btn_clear');
btnPost.addEventListener('click', function() {
addPost(inputPost.value)
});
btnClear.addEventListener('click', clearPosts);
displayExistingPosts();
<input id="input_post" type="text" value="">
<button type="button" id="btn_post">Post</button>
<button type="button" id="btn_clear">Clear</button>
<div id="posts"></div>
Since localStorage isn't supported in StackSnippets, here's a JSFiddle to help demonstrate.

Html button stops working after code run

I am making a game in HTML and JavaScript. I have a button that the user presses to 'run' a command they entered. But, after they have 'connected' to an ip the button no longer works, there is no error in the console. How can I fix this?
var ip = ["192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4"]
var gip;
var log;
var compname;
var svirus;
var connected = false;
function runcmd() {
var user = document.getElementById('code').value;
if (user == 'clear') {
l1.innerHTML = '';
l2.innerHTML = '';
l3.innerHTML = '';
l4.innerHTML = '';
l5.innerHTML = '';
l6.innerHTML = '';
l7.innerHTML = '';
l8.innerHTML = '';
l9.innerHTML = '';
l10.innerHTML = '';
};
if (user == 'connect') {
gip = prompt('Enter The Targets IP: ');
for (var key in ip) {
var user = document.getElementById('code').value;
if (ip[key] == gip) {
l1.innerHTML = 'Connecting to ' + gip;
l2.innerHTML = 'Connected to ' + gip;
connected = true;
grant.play()
l3.innerHTML = 'view bank';
l4.innerHTML = 'upload [virus]';
l5.innerHTML = 'disconnect [ip]';
var user = document.getElementById('code').value;
if (user == 'disconnect' + gip) {
connected = false;
l1.innerHTml = 'Disconnected Safely...';
};
if (user == 'view bank') {
var pwrd = Math.floor(Math.random() * 10000);
var nam = Math.floor(Math.random() * 10000);
alert(pwrd);
alert(nam);
var uname = 'user' + nam;
var user = prompt('Username: ');
var pass = prompt('Password: ');
if (user == uname && pass == pwrd) {
console.log('hello')
};
if (user == 'upload') {
svirus = prompt('Enter Virus: ');
for (var key in boughtviruses) {
if (boughtviruses[key] == svirus) {
l1.innerHTML = 'Uploading ' + svirus;
l2.innerHTML = 'Virus Uploaded';
}
else {
alert("You Don't Have This Virus!");
};
};
};
};
};
};
};
};
<span class="span" id="l1"></span><br />
<span class="span" id="l2"></span><br />
<span class="span" id="l3"></span><br />
<span class="span" id="l4"></span><br />
<span class="span" id="l5"></span><br />
<span class="span" id="l6"></span><br />
<span class="span" id="l7"></span><br />
<span class="span" id="l8"></span><br />
<span class="span" id="l9"></span><br />
<span class="span" id="l10"></span><br />
<span >C:\></span>
<input onclick="this.select()" id="code" class="inp" />
<button id="runcodeuser" onclick="runcmd()">Send Command</button>
You could create an event dispatcher. Every possible user input would be a separate event.
Separate the code to handle each event into different functions.
For example:
function user_clear () { ... }
function user_connect () { ... }
function user_bank () { ... }
function user_upload () { ... }
function dispatch_event (user)
{
switch (user)
{
case 'clear': user_clear (); break;
case 'connect': user_connect (); break;
case 'view bank': user_bank (); break;
case 'upload': user_upload (); break;
default: console.log ('dispatch_event: no such event: ' + user);
}
}
Then call it from runcmd():
function runcmd() {
var user = document.getElementById('code').value;
dispatch_event (user);
}
And also after running grant.play(): (inside user_connnect())
grant.play();
var user = document.getElementById('code').value;
dispatch_event (user);
Well, in your code only two "commands" are actually usable - clear and connect.
If the command, that is the value of the textbox, is connect, the browser will ask for the "targets IP". It then iterates through the IPs in the array declared at the top, and in each iteration again sets the variable user to the textbox value - but the textbox will still contain connect, and also the user-variable is already declared, so there's no need to user the var keyword again.
Because of this user == "view bank" for example will never evaluate to true. You'll have to restructure your code considerably for this to work as you want it to.
It would appear that your runcmd() function only has 3 blocks:
var user...
if (user=="clear") { ... }
if (user=="connect") { ... }
Everything else is in that last block/line. If user=="connect" is true, then the block executes, but user=="view bank", etc. will never be true.
There's no semicolon after grant.play() - and this function doesn't seem to be defined anywhere inside your code.
Also, for what it's worth, I do get an error message when running the snippet:
{
"message": "Script error.",
"filename": "",
"lineno": 0,
"colno": 0
}

Categories

Resources