When I output my code I get this output:
0[object Object]
1[object Object]
I believe this is because it is an object. Although I'm pretty noob, so I believe an object is an array. Correct me if that's wrong.
I noticed the object in my console:
Objectresult: Objectadmin_county: "Somerset"admin_district: "Sedgemoor"admin_ward: "Axevale"ccg: "NHS Somerset"codes: Objectcountry: "England"eastings: 343143european_electoral_region: "South West"incode: "2WL"latitude: 51.2870673059808longitude: -2.81668795540695lsoa: "Sedgemoor 001A"msoa: "Sedgemoor 001"nhs_ha: "South West"northings: 154531nuts: "Somerset"outcode: "BS26"parish: "Axbridge"parliamentary_constituency: "Wells"postcode: "BS26 2WL"primary_care_trust: "Somerset"quality: 1region: "South West"__proto__: Objectstatus: 200__proto__: Object
it maybe neater to look at this: https://api.postcodes.io/postcodes?lon=0.080647&lat=51.626281000000006&radius=115
I am trying to separate these parts into usable items stored as variables. I tried array[0] but that is undefined. Which I assume means I need to do something more like object(array[0])
I've been searching a while and I'm not getting anywhere.
Here's my full code that I was forking from elsewhere.
$(window).ready(function() {
$(initiate_geolocation);
});
function initiate_geolocation() {
navigator.geolocation.getCurrentPosition(handle_geolocation_query);
}
function handle_geolocation_query(position) {
var lat = position.coords.latitude;
var lon = position.coords.longitude;
var url = "https://api.postcodes.io/postcodes?lon=" + lon + "&lat=" + lat + "&radius=125";
post(url).done(function(postcode) {
displayData(postcode);
// console.log("postcode says: "+postcode);
console.log(postcode[0[1]]);
});
}
//display results on page
function displayData(postcode) {
var html = "";
$('#text').hide();
for (var index in postcode['result']) {
html += "<div class='row'>";
html += "<div class='cell'>";
html += index.replace(/_/g, ' ').strFirstUpper();
html += "</div><div class='cell'>";
html += postcode['result'][index];
html += "</div></div>";
console.log(postcode)
}
$('#text').html(html).fadeIn(300);
}
//ajax call
function post(url) {
return $.ajax({
url: url,
success: function() {
//woop
},
error: function(desc, err) {
$('#text').html("Details: " + desc.responseText);
}
});
}
//uppercase
String.prototype.strFirstUpper = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
#import url(//fonts.googleapis.com/css?family=Roboto);
html {
font-family: 'Roboto', sans-serif;
}
.header {
position: fixed;
z-index: 10;
width: 100%;
background: -moz-linear-gradient(90deg, #394D66, #3A5B85);
background: linear-gradient(90deg, #394D66, #3A5B85);
height: 80px;
min-width: 500px;
}
h1 {
font-weight: 400;
text-align: center;
margin: 0px;
font-size: 1.5em;
color: #9DC3EB;
text-transform: uppercase;
}
h1 span {
font-size: 0.8em;
text-transform: lowercase;
color: #E0E0E0;
}
.row {
width: 100%;
font-size: 1.2em;
padding: 5px 0px;
border-bottom: 1px solid #ccc;
}
.inputHolder {
width: 100%;
font-size: 20px;
text-align: center;
}
.inputHolder input {
text-align: center;
color: #333;
}
.cell {
display: inline-block;
width: 49%;
color: #393939;
}
.row .cell:first-child {
text-align: right;
padding-right: 10px;
}
.row:hover {
background: #ccc;
}
#text {
z-index: 0;
padding: 90px 0px;
width: 60%;
margin: 0px auto;
min-width: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<div class='header'>
<h1><span>Postcode Seach with</span> Postcodes.io</h1>
<!-- <div class='inputHolder'>
<input placeholder='Postcode' type='text' id='txtPostcode'/>
<input type='button' value='Search' id='btnPostcode'/>
</div>
-->
</div>
<div id='text'></div>
Eventually i want this code to ask you for permission to discover your location when you open the page and then find your post code (using postcode.io). I've got most of the way there but my noobishness is hurting me badly. Any help is much appreciated.
The code must be https to run geolocation.
Related
I am trying to deploy my first javascript application, which is a Chrome extension.
This simply generates random passwords and stores it with the url of current active tab.
App runs fine on local but after deploying it to Chrome, I got this error:
Uncaught TypeError: Cannot read properties of null (reading 'length')
index.js:65 (anonymous function)
I am a beginner, so any kind of criticism about my code is highly appreciated.
Thank you so much.
function render() {
*line65* **if(passwords.length === 0)** {
document.getElementById("saved-passwords-container").style.display= "none";
} else {
document.getElementById("saved-passwords-container").style.display= "unset";
}
let list = ""
**for (let i = 0; i < passwords.length; i++)** {
list += `<div class="saved-password-line"><span>${passwords[i]}</span></br></br><span class="link"><a target='_blank'href='${links[i]}'>${links[i]}</a></span></div>`
}
document.getElementById("passwords-el").innerHTML = list
}
Here is the full index.js file:
var characters = [];
for (var i=32; i<127; i++)
characters.push(String.fromCharCode(i));
for( var i = 0; i < characters.length; i++){
if ( characters[i] === '<') {
characters.splice(i, 1);
i--;
}
}
for( var i = 0; i < characters.length; i++){
if ( characters[i] === '>') {
characters.splice(i, 1);
i--;
}
}
let pw1El = document.getElementById("pw1-el")
let pw1 = ""
let passwords = []
passwords = JSON.parse(localStorage.getItem("savedPasswords"))
let links = []
links = JSON.parse(localStorage.getItem("savedLinks"))
render()
document.getElementById("char-count-el").value = 20
document.getElementById("gen-btn").addEventListener("click", function() {
var charCount = document.getElementById("char-count-el").value
pw1 = ""
for(let i = 0; i < charCount; i++) {
let randomIndex = Math.floor(Math.random() * characters.length)
pw1 += (characters[randomIndex])
}
pw1El.textContent = pw1
})
document.getElementById("save-btn").addEventListener("click", function() {
passwords.push(pw1El.innerText)
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
links.push(tabs[0].url)
})
localStorage.setItem("savedPasswords", JSON.stringify(passwords))
localStorage.setItem("savedLinks", JSON.stringify(links))
render()
})
function render() {
**if(passwords.length === 0)** {
document.getElementById("saved-passwords-container").style.display= "none";
} else {
document.getElementById("saved-passwords-container").style.display= "unset";
}
let list = ""
**for (let i = 0; i < passwords.length; i++)** {
list += `<div class="saved-password-line"><span>${passwords[i]}</span></br></br><span class="link"><a target='_blank'href='${links[i]}'>${links[i]}</a></span></div>`
}
document.getElementById("passwords-el").innerHTML = list
}
document.getElementById("clear-btn").addEventListener("click", function() {
passwords = []
links = []
localStorage.setItem("savedPasswords", JSON.stringify(passwords))
localStorage.setItem("savedLinks", JSON.stringify(links))
render()
})
document.getElementById("copy-btn").addEventListener("click", function() {
var input = document.getElementById("pw1-el").textContent;
navigator.clipboard.writeText(input);
alert("Copied Text: " + input);
})
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="container">
<h1>Generate a</br>random password</h1>
<p>Never use an unsecure password again.</p>
<hr>
<div>
<label for="char-count-el">Character Count:</label>
<input type="number" id="char-count-el">
<button id="gen-btn"><span>Generate password</span></button>
</div>
<div>
<label>Your Password:</label>
<div class="pw-container">
<span class="password-line" id="pw1-el">...</span>
<button class="side-btn" id="save-btn">SAVE</button>
<button class="side-btn" id="copy-btn">COPY</button>
</div>
</div>
<div id="saved-passwords-container">
<hr>
<label>Saved Passwords:</label>
<div class="pw-container">
<div id="passwords-el">...</div>
<button class="side-btn" id="clear-btn">CLEAR</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
index.css
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #ffffff;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
h1::first-line {
color: white;
}
h1 {
color: #00ffaa;
margin-bottom: 5px;
line-height: 1;
}
label {
font-size: 11px;
display: block;
color: #D5D4D8;
margin-top: 10px;
}
input {
height: 38px;
border-radius: 5px;
border: none;
width: 70px;
padding: 0px 10px;
text-align: center;
background-color: #D5D4D8;
margin-right: 20px;
font-size: 14px;
}
.container {
background: #1F2937;
margin: 0;
padding: 10px 30px 40px;
width: 100%;
min-width: 500px;
box-shadow: 0px 10px 30px 10px #2640644b;
display: flex;
flex-direction: column;
}
.pw-container {
display: flex;
border-radius: 5px;
background-color: #3e4f66;
padding: 10px;
margin-top: 10px;
}
.password-line {
color: #00ffaa;
font-size: 16px;
padding: 5px 10px;
margin-top: 0px;
flex-grow: 1;
flex: 1 1 1;
min-width: 0;
word-wrap: break-word;
white-space: pre-wrap;
word-break: break-word;
}
#passwords-el {
padding-right: 30px;
flex-grow: 1;
flex: 1 1 0;
min-width: 0;
word-wrap: break-word;
white-space: pre-wrap;
word-break: break-word;
}
.saved-password-line {
color: #D5D4D8;
font-size: 14px;
padding: 10px 15px;
border-bottom: solid 1px #d5d4d814;
border-radius: 5px;
margin-bottom: 10px;
line-height: 0.9;
}
a {
color: #d5d4d872;
text-decoration: underline;
}
.side-btn {
font-size: 12px;
width: 60px;
border: none;
background: none;
color: #D5D4D8;
padding: 5px 10px;
border-radius: 5px;
justify-self: flex-end;
}
.side-btn:hover {
background-color: #ffffff28 ;
}
#gen-btn {
color: #ffffff;
background: #0EBA80;
text-transform: capitalize;
text-align: center;
width: 200px;
height: 40px;
padding: 10px 10px;
border: none;
border-radius: 5px;
margin-bottom: 10px;
margin-top: 10px;
transition: all 0.5s;
box-shadow: 0px 0px 30px 5px #0eba8135
}
#gen-btn:hover {
box-shadow: 0px 0px 30px 10px #0eba8157
}
#gen-btn span {
cursor: pointer;
display: inline-block;
position: relative;
transition: 0.5s;
}
#gen-btn span:after {
content: '\279c';
position: absolute;
opacity: 0;
top: 0;
right: -20px;
transition: 0.5s;
}
#gen-btn:hover span {
padding-right: 25px;
}
#gen-btn:hover span:after {
opacity: 1;
right: 0;
}
p {
color: #D5D4D8;
margin-top: 0px;
}
hr {
border-width: 1px 0px 0px 0px;
border-color: #95959576;
margin: 15px 0;
}
manifest.json
{
"manifest_version": 3,
"version": "1.0",
"name": "Password Generator",
"action": {
"default_popup": "index.html",
"default_icon": "icon.png"
},
"permissions": [
"tabs"
]
}
I solved it.
I understand that (please correct me if I'm wrong)
if the local storage is empty, it does not return an empty array when parsed.
Apparently, when I do:
passwords = JSON.parse(localStorage.getItem("savedPasswords"))
passwords is no longer an array.
I instead use:
passwords.push(JSON.parse(localStorage.getItem("savedPasswords")))
But that just pushes a nested array inside passwords.
So I added a for loop, and used an if statement to address the initial error:
let locSavedPasswords = localStorage.getItem("savedPasswords")
if(locSavedPasswords !== null) {
for( var i = 0; i < (JSON.parse(locSavedPasswords)).length; i++){
passwords.push(JSON.parse(locSavedPasswords)[i])
}}
Initially, savedPasswords won't exist in localStorage, so localStorage.getItem('savedPasswords') will return null.
You then do JSON.parse(null), which doesn't immediately crash because null is first coerced to a string and becomes 'null' which is then JSON-parsed and turns back to null since the string with contents null is valid JSON.
But you then do .length on it and crash.
The solution is to handle the case where the item is not yet set and handle it like it was a JSON-stringified empty array. You can do so for example using the nullish coalescing operator ??:
let passwords = JSON.parse(localStorage.getItem("savedPasswords") ?? '[]')
Or, you can keep initializing it with [] as you did before but wrap the assignment with the actual value in a condition:
let passwords = []
const json = localStorage.getItem('savedPasswords')
if (json !== null) {
passwords = JSON.parse(json)
}
Personally, what I like to do for structured data in localStorage is something like this, which also handles the case that other things like invalid JSON somehow got stored there (without bricking the application):
let passwords = []
try {
const data = JSON.parse(localStorage.getItem('savedPasswords'))
if (Array.isArray(data)) passwords = data
} catch {}
I have just found a set of codes that fits my need right now for my blog.
Here I'll attach the code and a glimpse of what it looks like. Although It's still very simple.
What I want to ask is if it's possible to tweak these code possible using JS localstorage, so that it will keep all the saved text even after the user refresh the page, or even better if it stays there even after a user closed the window and reopened it later?
Here's what it looks like right now
and here is the code:
$(document).ready(function(){
var noteCount = 0;
var activeNote = null;
$('.color-box').click(function(){
var color = $(this).css('background-color');
$('notepad').css('background-color', color);
$('#title-field').css('background-color', color);
$('#body-field').css('background-color', color);
})
$('#btn-save').click(function(){
var title = $('#title-field').val();
var body = $('#body-field').val();
if (title === '' && body === '') {
alert ('Please add a title or body to your note.');
return;
}
var created = new Date();
var color = $('notepad').css('background-color');
var id = noteCount + 1;
if (activeNote) {
$('#' + activeNote)[0].children[0].innerHTML = title;
$('#' + activeNote)[0].children[1].innerHTML = created.toLocaleString("en-US");
$('#' + activeNote)[0].children[2].innerHTML = body;
$('#' + activeNote)[0].style.backgroundColor = color;
activeNote = null;
$('#edit-mode').removeClass('display').addClass('no-display');
} else {
var created = new Date();
$('#listed').append('<div id="note' + id + '" style="background-color: ' + color + '"><div class="list-title">' + title + '</div> <div class="list-date">' + created.toLocaleString("en-US") + '</div> <div class="list-text">' + body + '</div> </div>');
noteCount++;
};
$('#title-field').val('');
$('#body-field').val('');
$('notepad').css('background-color', 'white');
$('#title-field').css('background-color', 'white');
$('#body-field').css('background-color', 'white');
});
$('#btn-delete').click(function(){
if (activeNote) {
$('#' + activeNote)[0].remove();
activeNote = null;
$('#edit-mode').removeClass('display').addClass('no-display');
}
$('#title-field').val('');
$('#body-field').val('');
$('notepad').css('background-color', 'white');
$('#title-field').css('background-color', 'white');
$('#body-field').css('background-color', 'white');
});
$('#listed').click(function(e){
var id = e.target.parentElement.id;
var color = e.target.parentElement.style.backgroundColor;
activeNote = id;
$('#edit-mode').removeClass('no-display').addClass('display');
var titleSel = $('#' + id)[0].children[0].innerHTML;
var bodySel = $('#' + id)[0].children[2].innerHTML;
$('#title-field').val(titleSel);
$('#body-field').val(bodySel);
$('notepad').css('background-color', color);
$('#title-field').css('background-color', color);
$('#body-field').css('background-color', color);
})
})
header {
text-align: left;
font-weight: 800;
font-size: 28px;
border-bottom: solid 3px #DEDEDE;
display: flex;
justify-content: space-between;
}
footer {
display: flex;
flex-flow: row-reverse;
padding: 5px 20px;
}
.headers {
margin-top: 20px;
margin-bottom: -10px;
font-size: 20px;
}
#list-head {
margin-left: 2.5%;
width: 30.5%;
display: inline-block;
text-align: center;
}
#note-head {
width: 60%;
margin-left: 5%;
display: inline-block;
text-align: center;
}
noteList {
margin-top: 20px;
display: inline-block;
margin-left: 2.5%;
width: 30.5%;
height: 400px;
overflow: scroll;
border: solid 3px #929292;
border-radius: 5px;
background-color: #DEDEDE;
}
.within-list {
cursor: pointer;
}
.list-title {
font-weight: 600;
font-size: 20px;
padding: 5px 5px 0 5px;
}
.list-date {
font-weight: 200;
font-style: italic;
font-size: 12px;
padding: 0 5px 0 5px;
}
.list-text {
padding: 0 5px 5px 5px;
border-bottom: solid 1px black;
}
notePad {
display: inline-block;
border: solid 3px black;
border-radius: 10px;
height: 400px;
overflow: scroll;
width: 60%;
margin-left: 5%;
margin-top: 0;
}
#note-title {
font-size: 24px;
padding: 0 0 5px 5px;
border-bottom: solid 2px #DEDEDE;
}
#note-body {
padding: 5px;
}
#body-field, #title-field {
width: 100%;
border: none;
outline: none;
resize: none;
}
#title-field {
font-size: 18px;
font-weight: 600;
}
#body-field {
font-size: 14px;
font-weight: 500;
height: 400px;
}
#color-select {
display: flex;
flex-flow: row-reverse nowrap;
padding: 5px 10px 0 0;
}
.color-box {
border: solid 2px #929292;
height: 10px;
width: 10px;
margin-left: 5px;
}
.display {
display: visible;
}
.no-display {
display: none;
}
button {
margin: 5px;
border: solid 3px grey;
border-radius: 10%;
font-size: 22px;
font-weight: 800;
text-transform: uppercase;
color: #DEDEDE;
}
button:hover, .color-box:hover {
cursor: pointer;
}
#listed:nth-child(odd):hover {
cursor: pointer;
}
#btn-save {
background-color: #2F5032;
}
#btn-delete {
background-color: #E41A36;
}
.white {
background-color: white;
}
.orange {
background-color: #FFD37F;
}
.banana {
background-color: #FFFA81;
}
.honeydew {
background-color: #D5FA80;
}
.flora {
background-color: #78F87F;
}
.aqua {
background-color: #79FBD6;
}
.ice {
background-color: #79FDFE;
}
.sky {
background-color: #7AD6FD;
}
.orchid {
background-color: #7B84FC;
}
.lavendar {
background-color: #D687FC;
}
.pink {
background-color: #FF89FD;
}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title></title>
<link rel='stylesheet' href='style.css'>
</head>
<body>
<header>
The Note Machine
<div id='color-select'>
<div class='color-box white'></div>
<div class='color-box orange'></div>
<div class='color-box banana'></div>
<div class='color-box honeydew'></div>
<div class='color-box flora'></div>
<div class='color-box aqua'></div>
<div class='color-box ice'></div>
<div class='color-box sky'></div>
<div class='color-box orchid'></div>
<div class='color-box lavendar'></div>
<div class='color-box pink'></div>
</div>
</header>
<main>
<div class="headers">
<div id="list-head">
<b>Your Notes</b> <i>(click to edit/delete)</i>
</div>
<div id="note-head">
<b>Your Notepad</b>
<span id="edit-mode" class="no-display">
<i> (edit mode) </i>
</span>
</div>
</div>
<noteList>
<div id='listed'>
</div>
</noteList>
<notepad>
<div id="note-title">
<input id="title-field" type="text" placeholder="title your note">
</div>
<div id="note-body">
<textarea id="body-field"></textarea>
</div>
</notepad>
</main>
<footer>
<button id="btn-save">Save</button>
<button id="btn-delete">Delete / Clear </button>
</footer>
</body>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js'></script>
<script type='text/javascript' src='app.js'></script>
</html>
I tried searching in the net for other notepads, but they aren't working on my blog, and here's the one that is finally working. I would really appreciate any kind of suggestions and assistance. T
If all you want to do is save to LocalStorage when save is clicked, then it would be as simple as saving the title and body variables to LocalStorage in the $('#btn-save').click() handler.
Assuming that (as #Nawed Khan guessed) you want to have the note saved without the user having to click save, then you'll want to make three changes:
In the main body of your $(document).ready() function, check for existing LocalStorage values, and if they exist, then set them on your $('#title-field') and $('#body-field') elements.
Add two new change handlers to your $('#title-field') and $('#body-field') elements. When these change handlers fire, get the title and body values from the elements and save them to LocalStorage.
In the $('#btn-save').click() and $('#btn-delete').click() handlers, reset the LocalStorage values of the active note.
You should find these links useful:
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
https://api.jquery.com/change/
P.S. The information stored in LocalStorage can be lost if the user chooses to clear their browser data. If preservation of the data is vital, then implementing a solution using AJAX to connect to a database as #The Rahul Jha suggested would guarantee preservation of the data.
Yes , You can save the data in localStorage and fetch the data on page load. To set the localStorage item add below function in your script which is setting the item on keyup of textarea in localstorage.
$(document).on("keyup","#body-field",function(){
var text = $("#body-field").val();
localStorage.setItem("savedData", text);
});
Add below method to fetch the data from local storage
function loadDataFromLocalStorage(){
if (localStorage.getItem("savedData") !== null) {
$("#body-field").val(localStorage.getItem("savedData"))
}
}
And at last call the above method in $(document).ready() or page load to set the data back in text area after page load.
Put this inside the $(document).ready block:
$(“#title-field”).val(window.localStorage.getItem(“title”) || “”);
$(“#body-field”).val(window.localStorage.getItem(“body”) || “”);
$(“#title-field, #body-field”).change(function() {
var title = $(“#title-field”).val();
var body = $(“#body-field”).val();
window.localStorage.setItem(“title”, title);
window.localStorage.setItem(“body”, body)
})
The 2 first lines will load the text from the localStorage and sets the data on the corresponding inputs
The rest of the code is the part where the data is being saved to localStorage every time the value of #title-field OR #body-field changes.
I am building a simple scraping app that pulls data from an XML with format:
<entry>
<title>Title of something</title>
<summary>https://link_to_image_used_in_background</summary>
<link>www.link-to-website.com</link>
</entry>
that is being read by javascript:
$(document).ready(function() {
loadRSS('http://website.com/file.xml', '#Newsfeed', 'Heise');
});
function loadRSS(link, htmlContainer, author) {
var url = link;
var container = $(htmlContainer);
feednami.load(url, function(result){
if (result.error) {
console.log(result.error);
} else {
var entries = result.feed.entries;
for(var i = 0; i < 50; i++){
container.append("<li class=\"RSScard\"><p><h2>"
+ "" + entry.title + ' '
+ "</h2></p>"+ author +"</li>");
var bg_url = entry.summary
$(function () {
$(".RSScard").css({
backgroundImage: "url('" + bg_url + "')"
});
});
}
}
});
}
and is passed to CSS:
body {
background: #444;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
font-family: 'Roboto', sans-serif;
margin:0;
padding:0;
}
ul {
list-style-type: none;
}
#Newsfeed {
max-width: 1350px;
margin: 0 auto;
padding-top: 25px;
padding-bottom: 65px;
}
.RSScard {
padding: 20px 25px;
margin-left: 20px;
margin-top: 20px;
min-width: 200px;
max-width: 200px;
min-height: 225px;
opacity: .87;
background-image: var(plink);;
color: #388E3C;
font-size: 0.85em;
text-align: center;
overflow: hidden;
box-shadow: 0 0 8px rgba(0,0,0, 0.25);
float:left;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.RSScard a {
text-decoration: none;
color: #ededed;
font-size: 0.75em;
font-weight: 300;
opacity: 1;
}
.RSScard:hover {
opacity: 1;
background-color: #202B33;
}
.... my problem is that it that while the title and link are written to their respective space correctly, each space's background image is overwritten by the last xml entry's 'summary' child. My apologies for the probably poor coding and formatting - I initially took Tobias Totz's rss reader / feeder (https://codepen.io/tobias-totz/pen/rrJXqo) and tried to hotwire it. Thanks for your help!
The problem here is that you are setting the background image to all elements with class RSScard in every iteration of the loop. That's why you are able to see only the last item image because you have overridden the previous ones.
You would need to do something like the following to set a different image for each enty:
for(var entry in entries){
var $listElement = $("<li class=\"RSScard\".... </li>");
container.append($listElement);
$listElement.css({
backgroundImage: "url('" + entry.summary + "')"
});
}
$(document).ready(function() {
loadStreamInfo();
displayAll();
});
var allStreamInfo = [{ "user": "ogaminglol"}, { "user": "faceittv" }, { "user": "twitch"}, { "user": "hearthstonesea"}, { "user": "stephensonlance"}, {"user": "aegabriel" }];
function loadStreamInfo() {
for (var i = 0; i < 6; i++) {
$.ajax({
url: ("https://wind-bow.gomix.me/twitch-api/streams/" + allStreamInfo[i].user),
jsonp: "callback",
dataType: "jsonp",
success: function(data) {
if (data.stream == null) {
allStreamInfo[i]["status"] = "offline";
} else {
allStreamInfo[i]["status"] = "online";
}
}
});
}
for (var i = 0; i < 6; i++) {
$.ajax({
url: ("https://wind-bow.gomix.me/twitch-api/channels/" + allStreamInfo[i].user),
jsonp: "callback",
dataType: "jsonp",
success: function(data) {
allStreamInfo[i]["logo"] = data.logo;
allStreamInfo[i]["gameName"] = data.game;
allStreamInfo[i]["views"] = data.views;
allStreamInfo[i]["followers"] = data.followers;
allStreamInfo[i]["url"] = data.url;
}
});
}
}
function displayAll() {
for (var i = 0; i < 6; i++) {
var outString = "";
outString += "<div class='item'>";
outString += "<img src='" + allStreamInfo[i].logo + "' alt='logo'>";
outString += "<a href='" + allStreamInfo[i].url + "'><span id='gameName'>" + allStreamInfo[i].gameName + "</span></a>";
outString += "<span id='state'>" + allStreamInfo[i].status + "</span>";
outString += "<span id='views-block'>Views:<span id='view'>" + allStreamInfo[i].views + "</span></span>";
outString += "<span id='follow-block'>Followers:<span id='followed'>" + allStreamInfo[i].followers + "</span></span>";
outString += "</div>";
$("#result").append(outString);
}
}
body {
padding: 40px;
;
}
.toggle-button {
width: 400px;
color: white;
height: 100px;
text-align: center;
margin: 0 auto;
}
.all {
background-color: #6699CC;
width: 30%;
height: 70px;
line-height: 70px;
border-right: 2px solid grey;
display: inline;
float: left;
cursor: pointer;
}
.online {
cursor: pointer;
line-height: 70px;
background-color: cadetblue;
border-right: 2px solid grey;
width: 30%;
height: 70px;
display: inline;
float: left;
}
.offline {
cursor: pointer;
background-color: darkorange;
line-height: 70px;
width: 30%;
height: 70px;
display: inline;
float: left;
}
#result {
margin-top: 30px;
}
.item {
width: 500px;
height: 70px;
margin: 5px auto;
background-color: #666699;
border-left: 4px solid red;
color: whitesmoke;
/*border: 2px solid red;*/
}
a {
text-decoration: none;
}
img {
width: 50px;
height: 50px;
margin-top: 10px;
margin-left: 20px;
margin-right: 21px;
}
span#gameName,
span#views-block,
span#state,
span#follow-block {
position: relative;
bottom: 18px;
}
span#gameName,
span#state,
span#views-block {
margin-right: 21px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div class="toggle-button">
<div class="all" onclick="displayAll()">All</div>
<div class="online" onclick="displayOnline()">Online</div>
<div class="offline" onclick="displayOffline()">Offline</div>
</div>
<div id="result">
</div>
I want dynamically add property in JSON object.I have read post1 and post2. But why I got undefined property? allStreamInfo[i]["prop"] = "value" isn't the way to add property to a object? In the debug window, there is Uncaught TypeError: Cannot set property 'logo' of undefined(…). I have check the API call,it goes well.It seems I don't define the prop,but isn't it the way to dynamically add a prop?
As you are using $.ajax() which is an ansynchornous opertion in loop. When the get the result of ajax operation i will not have value with which it was initiated, So allStreamInfo[i] is undefined.
You can use Closures, to maintain the value of i till the ajax operation is complete
Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.
for (var i = 0; i < 6; i++) {
(function(j) {
$.ajax({
url: "https://wind-bow.gomix.me/twitch-api/streams/" + allStreamInfo[j].user,
jsonp: "callback",
dataType: "jsonp",
success: function(data) {
allStreamInfo[j]["status"] = data.stream == null ? "offline" : "online";
}
});
})(i);
}
Do read JavaScript closure inside loops – simple practical example
Well, above all, your code doesn't seem right to me. $.ajax returns a promise, which is a future object.
i becomes 6 when these promises are resolved (the loop terminates when i == 6). So in the success callback the expression becomes allStreamInfo[6]["status"].
Since allStreamInfo[6] is undefined in your code, the error is thrown.
you dealing with promises try this code
$(document).ready(function() {
loadStreamInfo();
});
var allStreamInfo = [{
"user": "ogaminglol"
}, {
"user": "faceittv"
}, {
"user": "twitch"
}, {
"user": "hearthstonesea"
}, {
"user": "stephensonlance"
}, {
"user": "aegabriel"
}];
var i = 0;
function loadStreamInfo() {
$.ajax({
url: ("https://wind-bow.gomix.me/twitch-api/channels/" + allStreamInfo[i].user),
jsonp: "callback",
dataType: "jsonp",
success: function(data) {
if (data.stream == null) {
allStreamInfo[i].status = "offline";
} else {
allStreamInfo[i].status = "online";
}
allStreamInfo[i].logo = data.logo;
allStreamInfo[i].gameName = data.game;
allStreamInfo[i].views = data.views;
allStreamInfo[i].followers = data.followers;
allStreamInfo[i].url = data.url;
i++;
if (i < allStreamInfo.length)
loadStreamInfo();
else
displayAll();
}
});
}
function displayAll() {
for (var i = 0; i < 6; i++) {
var outString = "";
outString += "<div class='item'>";
outString += "<img src='" + allStreamInfo[i].logo + "' alt='logo'>";
outString += "<a href='" + allStreamInfo[i].url + "'><span id='gameName'>" + allStreamInfo[i].gameName + "</span></a>";
outString += "<span id='state'>" + allStreamInfo[i].status + "</span>";
outString += "<span id='views-block'>Views:<span id='view'>" + allStreamInfo[i].views + "</span></span>";
outString += "<span id='follow-block'>Followers:<span id='followed'>" + allStreamInfo[i].followers + "</span></span>";
outString += "</div>";
$("#result").append(outString);
}
}
body {
padding: 40px;
;
}
.toggle-button {
width: 400px;
color: white;
height: 100px;
text-align: center;
margin: 0 auto;
}
.all {
background-color: #6699CC;
width: 30%;
height: 70px;
line-height: 70px;
border-right: 2px solid grey;
display: inline;
float: left;
cursor: pointer;
}
.online {
cursor: pointer;
line-height: 70px;
background-color: cadetblue;
border-right: 2px solid grey;
width: 30%;
height: 70px;
display: inline;
float: left;
}
.offline {
cursor: pointer;
background-color: darkorange;
line-height: 70px;
width: 30%;
height: 70px;
display: inline;
float: left;
}
#result {
margin-top: 30px;
}
.item {
width: 500px;
height: 70px;
margin: 5px auto;
background-color: #666699;
border-left: 4px solid red;
color: whitesmoke;
/*border: 2px solid red;*/
}
a {
text-decoration: none;
}
img {
width: 50px;
height: 50px;
margin-top: 10px;
margin-left: 20px;
margin-right: 21px;
}
span#gameName,
span#views-block,
span#state,
span#follow-block {
position: relative;
bottom: 18px;
}
span#gameName,
span#state,
span#views-block {
margin-right: 21px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div class="toggle-button">
<div class="all" onclick="displayAll()">All</div>
<div class="online" onclick="displayOnline()">Online</div>
<div class="offline" onclick="displayOffline()">Offline</div>
</div>
<div id="result">
</div>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
This code is an excerpt from a larger project, but I have tried to pull out the relevant material and provide that only.
I have a project, and the part that I need help with is this:
Product codes are generated by users via a series of drop-downs and radio buttons. The one part that will always stay the same is that there is a
(x11)
at the end of each line with a product number, where 11 represents the quantity of the product code, and will also change.
A demo of the relevant code is available at This Fiddle.
My problem is this: the deleteItem() function works when the code is displayed as
ca-fefefsefef (x45)
but not when I tried to change the format to display the quantity as
ca-fjeoisfne Qty. 78
(The difference being in the way the quantity is displayed, not the code itself)
All of the product codes are examples, are not real, and the actual codes will vary in length and content. The quantity of each product code will change as well.
I suppose what I am asking for is a new regex to replace the old one in the deleteitem() function, but this regex needs to work with
Qty. 23
where 23 is the quantity, and will change from code to code.
Basically, the selection of code that I have provided at the fiddle is designed to display each product code and its corresponding quantity in a drop down. The codes are stored in an array, as well as the quantities(in a separate array). The purpose of the deleteitem() function is when the delete button is clicked next to a product code and quantity, it not only deletes the product code and quantity from the drop-down, but it also deletes the corresponding items in the product_codes and quantities arrays. (with the help of the removetextfromarray() function)
Make sure to watch the web console, it will display the arrays before and after the items are deleted. You'll note that when the quantity is displayed as (x99), it works, but if you change it to Qty. 99, it removes the items from the dropdown, but does not remove the corresponding items from their arrays.
So what I need is a new regex to replace the old one (or possibly a new/updated deleteitem() function that will work with the quantity display format as
Qty. 3
instead of
(x3)
and will delete both the items both from the drop down, and delete the two items from their corresponding arrays.
Please keep in mind the following: The product codes in the array, and the quantities in their own array will change, the ones I have provided are examples. There may be more than three, and they will change in length. I am also unable to use Jquery.
If you can spare the time, I would love any help you can give. I've spent literally hours trying to build new regexes that will work, trying to uncode the existing one (I didn't write it) and such. A working fiddle would be absolutely GREAT. Thanks so much for any help.
If I'm not being clear, please comment and I'll be happy to answer any questions about it or make updates. Thanks again!
How about this: /\w*Qty\. \d+$/
(see example here https://jsfiddle.net/xes3eLxp/1/)
That means, match:
Zero or more white space characters (\w*),
Qty. (Qty\.),
A single space (),
One or more digits (\d+),
The end of the line ($).
Consider the sample string: "ckj-fjeieofj Qty. 56"
The above regex would match Qty. 56
product_codes = ['cr-rttrnhuj3', 'ckj-fjeieofj', 'jjff-cr-sd'];
quantities = ['2', '56', '98'];
myfunction = function () {
document.getElementById('cart_body').innerHTML = '';
cart_text = '';
emp = '<div class="close_button" onclick="deleteItem(this)">x</div>';
open_span = '<span class="close_span">';
close_span = '</span>';
elf = '<br class="none"/>';
for (i = 0; i < product_codes.length; i++) {
cart_text += "<div>" + open_span + product_codes[i] + " Qty. " + quantities[i] + close_span + emp + elf + "</div>";
}
document.getElementById('cart_body').innerHTML = cart_text;
}
function removeTextFromArray(array, text){
for (var i=array.length-1; i>=0; i--) {
if (array[i] === text) {
array.splice(i, 1);
quantities.splice(i, 1);
return array;
}
}
}
myfunction();
hider2 = function () {
cart_bod = document.getElementById('cart_body');
cart_bod.classList.toggle('closed');
}
//below function is the important one
deleteItem = function (item) {
//dot instead of hashtag
item.parentElement.remove();
console.log('set');
var textInNode = item.parentElement.getElementsByClassName("close_span")[0].innerHTML;
textInNode = textInNode.replace(/\w*Qty\. \d+$/g, "").trim();
//new regex is /*\Qty[^)]*\ */g
//old is / *\([^)]*\) */g
codes = removeTextFromArray(product_codes, textInNode);
console.log(product_codes)
console.log(quantities);
}
body {
font: 12px tahoma;
}
.centered {
border: 2px solid transparent;
margin: 0 auto;
width: 90%;
margin-bottom: 10px;
}
#debug-box {
}
#configurator-container {
}
#submit-box {
width: 400px;
height: 50px;
margin-bottom: 5px;
}
#unit-container {
border: 2px solid transparent;
width: 50%;
/*change this width to test whether it'll fit in the SEI website'*/
}
#quantity {
width: 40px;
}
.select-label {
}
dt {
float: left;
width: 45%;
text-align: right;
cursor: default;
}
br {
margin-bottom: 30px;
}
.none {
margin-bottom: 0px;
}
.s_container {
margin-top: 20px;
}
.sm_it {
font-style: italic;
}
i {
padding-left: 20px;
font-size: 10px;
}
input[type='email'] {
width: 235px;
}
.second_line_italics {
padding-left: 40px;
}
#configurator-container {
background-image: url("data:image/gif;base64,R0lGODlhBgAGAKIAANbXy+Hi29rc08THu9HWy8zQwwAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOkYzM0I5RTQ3Q0UwRUUwMTFCMzMzRkRGNDFGODlGRDVEIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkY2QjNGNjE4ODQ5ODExRTA4MUU4OTkzQzdFOTQ5MDU5IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkY2QjNGNjE3ODQ5ODExRTA4MUU4OTkzQzdFOTQ5MDU5IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzQgV2luZG93cyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjcyMDlGMEYwQjg2QUUwMTFCOTg2OTk5N0I0QjM1NDEyIiBzdFJlZjpkb2N1bWVudElEPSIxNzA3NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh5N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAAAAAAALAAAAAAGAAYAAAMQSBpcLnBIQFlQBApXKJBDAgA7");
}
select {
width: 235px;
}
input[type='number'] {
width: 235px;
}
.twin_btns {
display: inline;
cursor: pointer;
}
.twin_divs {
margin: 0 auto;
margin-top: 10px;
z-index: 300;
position relative;
text-align: center;
}
#second_line_ex-length {
width: 215px;
margin-left: 20px;
}
#b-length-1 {
width: 145px;
}
#b-length-2 {
width: 145px;
}
.hidden {
color: grey;
pointer-events: none;
pointer: default;
border-color: grey;
}
.contact-i-header {
font-weight: bold;
font-size: 18px;
}
input[type='text'] {
width: 235;
}
#request-quote-container {
height: 60px;
width: 90%;
margin:0 auto;
border-bottom: 1px solid #ADAEA9;
font-family: Tahoma;
background-color: #DADCD3;
}
h2 {
opacity: .8;
width: 284.917px;
text-align: right;
}
.side-by-side {
display: inline-block;
}
h5 {
margin-left: 40px;
}
#item {
margin-top: 5px;
}
#triangle-up {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid black;
opacity: 0.6;
}
.slider {
overflow-y: hidden;
transition-property: all;
transition-duration: 5s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
}
.slider.closed {
max-height: 0;
}
.slider2 {
overflow-y: hidden;
transition-property: all;
transition-duration:.5s;
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
max-height: 200px;
}
.slider2.closed {
max-height: 0;
}
#submit_info {
text-align: center;
margin: 0 auto;
}
.bottom_btns {
}
#sent_box {
height: 20px;
text-align: center;
}
#write_box {
height: 20px;
text-align: center;
}
#send_box {
height: 20px;
text-align: center;
}
.cart_parts {
border: 1px solid black;
box-sizing: border-box;
width: 60%;
margin: 0 auto;
}
#cart_top {
height: 40px;
font-family: Tahoma;
background-color: #DADCD3;
margin: 0 auto;
box-shadow:
}
#cart_body {
text-align: center;
}
.close_button {
border: 1px solid black;
width: 12px;
height: 12px;
border-radius: 90px;
font-size: 12px;
text-align: center;
line-height: 11px;
background-color: lightGrey;
display: inline-block;
margin-left: 20px;
}
.close_span {
display: inline-block;
}
.close_button:hover {
color: red;
border: 2px solid red;
font-weight: bold;
}
#script_no {
color: red;
text-align: center;
font-size: 16px;
}
#not_supported {
text-align: center;
color: red;
}
#ter {
margin-bottom: 30px;
background-color: red;
}
#submit-box {
margin: 45px auto;
}
#tbr {
margin-bottom:10px;
}
<div id='cart_top' class='cart_parts'> <dt class='list-item' style='margin-top: 10px;'>
View your Quote
</dt>
<dd class='list-item'>
<div id='triangle-up' class='side-by-side' style='float: right; margin-right: 20px; cursor: pointer; margin-top: 15px;' onClick='hider2()'></div>
</dd>
</div>
<div id='cart_body' class='cart_parts slider2 closed'></div>