This question already has answers here:
Why is there "undefined" text in the beginning of my string?
(3 answers)
Closed 4 years ago.
I have a code like this:
var students = [
{
name: 'Mustafa',
track: 'A',
achievements: 5,
points: 500
},
{
name: 'Ersin',
track: 'B',
achievements: 6,
points: 600
},
{
name: 'Ahmet',
track: 'C',
achievements: 7,
points: 700
},
{
name: 'Mehmet',
track: 'D',
achievements: 8,
points: 800
},
{
name: 'Cafer',
track: 'E',
achievements: 9,
points: 900
}
];
var HTML;
var s = 0;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
for (var s = 0; s < students.length; s += 1) {
HTML += '<h2>' + 'Student: ' + students[s].name + '</h2>' ;
HTML += '<p>' + 'Track: ' + students[s].track + '</p>';
HTML += '<p>' + 'Points: ' + students[s].points + '</p>';
HTML += '<p>' + 'Achievements: ' + students[s].achievements + '</p>';
};
print(HTML);
<div id="output"></div>
Unfortunately, only bad-outcome for this code is an "undefined" at the beginning. I would like to get rid of this.
Is it something about my loop or any other detail that i couldn't predict?
var HTML;
You don't explicitly give the variable a value when you initialise it, so it is undefined.
The first time you append to the variable with +=, that value gets implicitly converted to the string "undefined".
Use var HTML = ""; instead.
Initialize HTML to "", you are getting undefined since HTML (since it is not initialized) is undefined
var HTML = ""; //change this line
Demo
var students = [
{
name: 'Mustafa',
track: 'A',
achievements: 5,
points: 500
},
{
name: 'Ersin',
track: 'B',
achievements: 6,
points: 600
},
{
name: 'Ahmet',
track: 'C',
achievements: 7,
points: 700
},
{
name: 'Mehmet',
track: 'D',
achievements: 8,
points: 800
},
{
name: 'Cafer',
track: 'E',
achievements: 9,
points: 900
}
];
var HTML = ""; //change this line
var s = 0;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
for (var s = 0; s < students.length; s += 1) {
HTML += '<h2>' + 'Student: ' + students[s].name + '</h2>' ;
HTML += '<p>' + 'Track: ' + students[s].track + '</p>';
HTML += '<p>' + 'Points: ' + students[s].points + '</p>';
HTML += '<p>' + 'Achievements: ' + students[s].achievements + '</p>';
};
print(HTML);
<div id="output"></div>
Initialize HTML variable with an empty string like this:
var HTML="";
Related
I need to display list of all songs saved in array. I need to get audio duration for each list element. Can I do it automatically or do I have to add duration to the array myself?
let tracks = [
{
name: "Song 1",
artist: "Monica",
path: "..song1.mp3",
},
{
name: "Song 2",
artist: "Carol",
path: "..song2.mp3"
},
{
name: "Song 3",
artist: "Sam",
path: "..song3.mp3"
},
];
let list = "<ul>";
for (let i = 0; i < tracks.length; i++) {
list += '<li>';
list += '<div class="name">' + tracks[i].name + '</div>';
list += '<div class="artist">' + tracks[i].artist + '</div>';
list += '<div class="duration">XX:XX</div>';
list += 'Download';
list += '</li>';
}
let list = "</ul>";
playlist.innerHTML = list;
You need to add audio element to get the duration and make this element as hidden if you don't want to display it.
You can also use any plugin if you needed.
let tracks = [{
name: "Song 1",
artist: "Monica",
path: "https://download.samplelib.com/mp3/sample-3s.mp3",
},
{
name: "Song 2",
artist: "Carol",
path: "https://download.samplelib.com/mp3/sample-6s.mp3"
},
{
name: "Song 3",
artist: "Sam",
path: "https://download.samplelib.com/mp3/sample-9s.mp3"
},
];
function getDuration() {
var audio = document.getElementsByTagName('AUDIO');
for (let i = 0; i < audio.length; i++) {
let duration = document.querySelector('[id="myAudio' + i + '"]').duration;
console.log(duration);
document.getElementById("duration" + i).innerHTML = duration;
}
}
let list = "<ul>";
for (let i = 0; i < tracks.length; i++) {
list += '<li>';
list += '<div class="name">' + tracks[i].name + '</div>';
list += '<div class="artist">' + tracks[i].artist + '</div>';
list += '<div id="duration' + i + '" class="duration">00:00</div>';
list += 'Download';
// you need to add hidden audio element to get the duration
list += '<audio hidden id="myAudio' + i + '" controls><source src="' + tracks[i].path + '" type="audio/mpeg"> Your browser does not support the audio element.</audio>'
list += '</li>';
}
list += "</ul>";
var playlist = document.getElementById("playListDiv");
playlist.innerHTML = list;
// get duration after the html is loaded
setTimeout(function() {
getDuration();
}, 1000);
<html>
<body>
<div id="playListDiv"></div>
</body>
</html>
You can also add duration in array to avoid extra Audio element
So I have a small RPG im coding (well I started it ages ago and gave up but have just come back for naother look!). I have a main character (just one so far):
var heroes = [{
name: 'Mary',
health: 15,
weapon: 'sword',
damage: 8,
dodge: 8,
backpack: 'water',
experience: 5
}];
Can I add extra items to the backpack or as I suspect (the below) is this the wrong way of storing the information as I get an error.
backpack: 'water', 'bread', 'cheese',
Secondly and related... I have a function to fight an enemy. When it is defeated the content of their backpack would be pushed to the hero's backpack. I thought something like the below would work, but again Im clearly wrong :)
All help gratefully accepted :)
Full code:
<h1>
<b>RPG Battle</b>
</h1>
<p><button id="fight">Fight</button><button id="reset">Reset</button></p>
<div id="output"></div>
<script>
var enemies = [{
name: 'Wizard',
health: 10,
weapon: 'his staff.',
damage: 12,
dodge: 10,
backpack: 'Cloak of Invisibility....'
},
{
name: 'Elf',
health: 4,
weapon: 'a dagger.',
damage: 6,
dodge: 8,
backpack: 'a bow & Arrow....'
},
{
name: 'Dragon',
health: 20,
weapon: 'a fireball.',
damage: 15,
dodge: 2,
backpack: 'a golden key...'
},
{
name: 'Goblin',
health: 12,
weapon: 'his bow and arrow....',
damage: 4,
dodge: 6,
backpack: 'gold coins....'
},
{
name: 'Dwarf',
health: 7,
weapon: 'his axe.',
damage: 5,
dodge: 4,
backpack: 'a treasure map....'
},
{
name: 'Orc',
health: 8,
weapon: 'a sword.',
damage: 5,
dodge: 5,
backpack: 'a silver tooth....'
},
{
name: 'Witch',
health: 6,
weapon: 'her potion of the undead....',
damage: 7,
dodge: 6,
backpack: 'a potion of the living....'
},
{
name: 'Old Lady',
health: 3,
weapon: 'her frying pan.',
damage: 1,
dodge: 1,
backpack: 'some fruit and vegetables....'
},
{
name: 'Villagers',
health: 15,
weapon: 'sharpened sticks.',
damage: 5,
dodge: 1,
backpack: 'some meat....'
},
{
name: 'Thief',
health: 4,
weapon: 'his fists.',
damage: 3,
dodge: 9,
backpack: 'a bag of jewels....'
}
];
var heroes = [{
name: 'Mary',
health: 15,
weapon: 'sword',
damage: 8,
dodge: 8,
backpack: '',
experience: 5
}];
function getRandomElement(list) {
return Object.create(list[Math.floor(Math.random() * list.length)]);
}
function getRandomEnemy() {
return getRandomElement(enemies);
}
function getRandomHero() {
return getRandomElement(heroes);
}
var x, randomEnemy, hero;
var output = document.getElementById("output");
var fightBtn = document.getElementById("fight");
var resetBtn = document.getElementById("reset");
fightBtn.addEventListener("click", battle);
function reset() {
x = 1;
randomEnemy = getRandomEnemy();
fightBtn.disabled = false;
hero = getRandomHero();
output.innerHTML = "";
}
resetBtn.addEventListener("click", reset);
reset();
function battle() {
if (hero.health <= 0 || randomEnemy.health <= 0) {
fightBtn.disabled = true;
return;
}
var enemyDamage = Math.floor((Math.random() * (randomEnemy.damage)) + 1);
var enemyDodge = Math.floor((Math.random() * (randomEnemy.dodge)) + 1);
var randomNumber = Math.floor(Math.random() * 7) + 1;
var heroDodge = [Math.floor(Math.random() * hero.dodge)];
var heroDamage = Math.floor((Math.random() * hero.damage) + 1);
var heroExperience = Math.floor(Math.random() * 5) + 1;
output.innerHTML += "<br>" + "<b>" + "Round " + x++ + "</b>";
output.innerHTML += "<br>" + "The " + randomEnemy.name + " attacks you with " + randomEnemy.weapon;
if (randomNumber < heroDodge) {
output.innerHTML += "<br>" + "You evade the attack!";
} else if (hero.health > 0) {
hero.health = hero.health - enemyDamage;
if (hero.health < 0)
hero.health = 0;
output.innerHTML += "<br>" + "The " + randomEnemy.name + " did " + enemyDamage + " damage";
output.innerHTML += "<br>" + "You have " + hero.health + " health remaining.";
}
if (hero.health <= 0) {
output.innerHTML += "<br>" + "You have been killed by the " + randomEnemy.name;
fightBtn.disabled = true;
return;
} else {
output.innerHTML += "<br>" + hero.name + " attacks the " + randomEnemy.name + " with their " + hero.weapon;
}
if (randomNumber < enemyDodge) {
output.innerHTML += "<br>" + "The " + randomEnemy.name + " evades the attack!";
} else if (randomEnemy.health > 0) {
randomEnemy.health = randomEnemy.health - heroDamage;
if (randomEnemy.health < 0)
randomEnemy.health = 0;
output.innerHTML += "<br>" + hero.name + " did " + heroDamage + " damage";
output.innerHTML += "<br>" + "The " + randomEnemy.name + " has " + randomEnemy.health + " health";
}
if (randomEnemy.health <= 0) {
output.innerHTML += "<br>" + "The " + randomEnemy.name + " dies! You find " + randomEnemy.backpack;
output.innerHTML += "<br>"
output.innerHTML += "<br>" + "You gain " + heroExperience + " XP";
output.innerHTML += "<br>" + "You have " + hero.health + " health left";
output.innerHTML += "<br>" + hero.backpack.push(randomEnemy.backpack);
output.innerHTML += "<br>" + "Your backpack contains " + hero.backpack;
fightBtn.disabled = true;
}
}
</script>
initialization of the hero should be:
var heroes = [{
name: 'Mary',
health: 15,
weapon: 'sword',
damage: 8,
dodge: 8,
backpack: ['water', 'some other stuff'], //empty backpack is ['']
experience: 5
}];
Now the backpack is an array you can push into.
So after the replies above I managed to work out (guess) that the line reading:
output.innerHTML += "<br>" + hero.backpack.push(randomEnemy.backpack);
should be changed to:
output.innerHTML += "<br>" + hero.backpack.push([randomEnemy.backpack]);
I need to sort an object by the value to an object inside it.
is it possible to sort without converting it to an array first ?
I create this object by checking if 3 other arrays have its own property and adding it all to one object.
I have tried sorting function inside and out side of for/in loop.
//how i created the object
var htmlDep = document.getElementById("departmentTable")
var tableElem = document.createElement("table");
var tdList = "";
tableElem.innerHTML = "<tr><th class='avdeling'>Avdeling</th><th class='avdeling'>Aktiv Ansatt</th><th class='avdeling'>Ny Ansatt</th><th class='avdeling'>Sluttet Ansatt</th></tr>"
var obj = {}
var distribution = ["manager", "salesMan", "consultant"]
for (var i = 0; i < distribution.length; i++) {
var work = distribution[i];
obj[work] = {
active: 0,
notActive: 0,
quit: 0
} // using 0 as default
if (active.hasOwnProperty(work)) {
obj[work].active = active[work]
}
if (notActive.hasOwnProperty(work)) {
obj[work].notActive = notActive[work]
}
if (quit.hasOwnProperty(work)) {
obj[work].quit = quit[work]
}
tdList += "<tr><td>" + work + "</td>" + "<td>" + obj[work].active + "</td>" + "<td>" + obj[work].notActive + "</td>" + "<td>" + obj[work].quit + "</td></tr>"
}
tableElem.innerHTML += tdList;
htmlDep.appendChild(tableElem)
//Object example
obj = {
manager: {
active: 450,
notActive: 20,
quit: 0
},
salesMan: {
active: 150,
notActive: 5,
quit: 3
},
ceo: {
active: 50,
notActive: 55,
quit: 0
},
consultant: {
active: 5,
notActive: 72,
quit: 30
}
}
<div id="departmentTable">
</div>
I want to sort the object by the notActive value from high to low inside HTML table
I need to loop through an array of objects, and prompt the user to enter a student's name. if the name exists I need to print the student's data to the screen or else keep on iterating until the user types quit.
The issue I have is, if I type the name of student of the last object, the student's records will not print until the loop completes.
Please see the code below:
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
// Access each students records in the array / a loop is needed to achieve this
for (var i = 0; i < students.length; i++) {
student = students[i];
console.log(student);
search = prompt('Please enter a student\'s name to see his records: ');
search = search.toLocaleLowerCase();
console.log(search);
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
} else if (search === 'quit') {
break;
}
}
// Print the students' name; track, achievments and points
print(records);
What I need is, to be able to print the records of a student, from the first prompt even if he's the last on the list.
What you have done it's more like a guessing game : "find the name of the current student in the for loop"
I don't know if you still need an answer but here you go :
You only have to put the prompt before the for loop.
After the prompt you do the loop and stop if you find a result.
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
search = prompt('Please enter a student\'s name to see his records: ');
// Access each students records in the array / a loop is needed to achieve this
for (var i = 0; i < students.length; i++) {
student = students[i];
search = search.toLocaleLowerCase();
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
}
}
// Print the students' name; track, achievments and points
print(records);
<div id="output"></div>
You can add a if statement on your loop.
if( search != "quit") {
for (var i = 0; i < students.length; i++) {
student = students[i];
search = search.toLocaleLowerCase();
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
}
}
}
With it, if you type quit you will not enter in the loop.
Even if it not fill your requirement the better way of doing it is using find method.
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function write(student) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
print(records);
}
search = prompt('Please enter a student\'s name to see his records: ');
student = students.find((element) => {
if (element.name == search) {
return true;
}
})
if (student) {
write(student);
};
// Print the students' name; track, achievments and points
<div id="output"></div>
Instead of looping over students to prompt the user, you need to continue prompting the user until they enter quit or you have a match.
Something like this:
var quit = false
while(!quit) {
search = prompt('Please enter a student\'s name to see his records: ');
search = search.toLocaleLowerCase();
if (search === 'quit') {
quit = true;
continue;
}
// search for student here and if match is found then set quit to true
}
I need to loop through an array of objects, and prompt the user to enter a student's name. if the name exists I need to print the student's data to the screen or else keep on iterating until the user types quit.
You need to rethink your algorithm:
get input from user
while user does not enter "quit"
for each object in list
if name is the same as input
output the record
get input from user
Note that you need to get the input from the user then iterate over the list to search for the correct object.
Alternatively, you could use an object instead of a list. This outer object would have the student's name as a key and the object record as a value. Now you can index on the student's name that the user inputs to get the record directly rather than searching through a list.
I'm trying to use a for-loop to reiterate over the object material and enter the material into a div on my html. Right now I have the code set to accept an array, but I'd like to use an object instead.
var animals = [
{
name:'Aye Aye',
description: 'blue',
img: 'http://cdnimg.in/wp-content/uploads/2015/06/335.jpg?cfaea8',
price:500
}, {
name:'Little Imp',
description:'yellow',
img:'http://cdnimg.in/wp-content/uploads/2015/06/334.jpg?cfaea8',
price:3000
}, {
name:'Long Nose Monkey',
decription:'grey',
img:'http://cdnimg.in/wp-content/uploads/2015/06/492.jpg?cfaea8',
price:5000
}, {
name:'Nicobar Bird',
decription:'purple',
img:'http://cdnimg.in/wp-content/uploads/2015/06/471.jpg?cfaea8',
price: 6
}, {
name:'Slow Loris',
decription: 'brown',
img: 'https://s-media-cache-ak0.pinimg.com/736x/49/09/8f/49098fbc3c9a37fb03034b45e89c5cd4.jpg',
price:90
}, {
name:'Tucan',
decription:'orange',
img: 'http://cdnimg.in/wp-content/uploads/2015/06/526.jpg?cfaea8',
price:100
}, {
name:'Fennec Fox'
decription:'yellow'
img:'http://cdnimg.in/wp-content/uploads/2015/06/526.jpg?cfaea8',
price:500
}, {
name:'Sugar Glider',
description: 'green',
img: 'https://pbs.twimg.com/media/CNd03WIUwAAqKHg.jpg:large',
price:1000000
}
]
function animal() {
// var animalName = ['Aye Aye',
var animalElement = document.getElementById("div0");
for (i=0; i<animalName.length; i++) {
animalElement.innerHTML += '<h2>' + animalName[i]+'</h2>' +'<p>' + animalDescription[i] +'</p>' + '<p>' + animalPrice[i] +'</p>' + '<p>' + animalImage[i] + '</p>';
};
};
animal();
This is a simple solution based off of what you currently have:
function generateAnimals() {
var animalElements = document.getElementById("div0");
var html = '';
for (i = 0; i < animals.length; i++) {
var animal = animals[i];
html += '<h2>' + animal.name + '</h2>'
+ '<p>' + animal.description + '</p>'
+ '<p>' + animal.price + '</p>'
+ '<p>' + animal.image + '</p>';
}
animalElements.innerHTML += html;
}
generateAnimals();
Just be warned that creating elements like this can get messy once things start to become more complex.