Using forEach() on an Array of Objects - javascript

I know how to get all the information on the web page another way, but I am trying to get it on the web page with the forEach() method to learn something new. This is my first time using the forEach() method can someone please tell what I am doing wrong? Everything but the values get printed onto the web page.
let students = [
{ name: "Milla Jovovich", track: "Fullstack JavaScript", achievements: 5, points: 50 }
,{ name: "Bjon Aarseth", track: "iOS Development", achievements: 7, points: 70 }
,{ name: "Varg Oystein", track: "Front End Development", achievements: 12, points: 120 }
,{ name: "Wilhelm Striepe", track: "Software Engineering", achievements: 9, points: 90 }
,{ name: "Anders Hansen", track: "Data Science", achievements: 22, points: 220 }
] ;
let message = "";
let student;
let search;
function print(message) {
let outputDiv = document.getElementById("output") ;
outputDiv.innerHTML = message ;
}
students.forEach(function(myElement) {
for(let key in myElement) {
myElement += "<h2>Student: " + myElement[key] + "</h2>" ;
myElement += "<p>Track: " + myElement[key] + "</p>" ;
myElement += "<p>Achievements: " + myElement[key] + "</p>" ;
myElement += "<p>Points: " + myElement[key] + "</p>" ;
}
print(myElement) ;
}) ;
<div id="output">

You have a few issues:
Your inner for-loop is redundant as it adds the same value to every information block. Instead, you can remove it and access only the required keys for each of your objects (using dot-notation).
You are trying to concatenate a string with your object when you do myElement += "string" as myElement represents a given object in your array. Instead, you can use your empty string (message) and add to that at each iteration of your loop.
Once you have done that, your message variable will contain the mark-up you need to print once your .forEach loop is complete, and so you can move the print() line to be outside your for loop.
See example below:
let students = [{
name: "Milla Jovovich",
track: "Fullstack JavaScript",
achievements: 5,
points: 50
},
{
name: "Bjon Aarseth",
track: "iOS Development",
achievements: 7,
points: 70
},
{
name: "Varg Oystein",
track: "Front End Development",
achievements: 12,
points: 120
},
{
name: "Wilhelm Striepe",
track: "Software Engineering",
achievements: 9,
points: 90
},
{
name: "Anders Hansen",
track: "Data Science",
achievements: 22,
points: 220
}
];
let message = "";
function print(message) {
let outputDiv = document.getElementById("output");
outputDiv.innerHTML += message;
}
students.forEach(function(myElement) {
message += "<h2>Student: " + myElement.name + "</h2>";
message += "<p>Track: " + myElement.track + "</p>";
message += "<p>Achievements: " + myElement.achievements + "</p>";
message += "<p>Points: " + myElement.points + "</p>";
});
print(message);
<div id="output"></div>

You don't need to iterate over your element with for...in. The forEach is enough.
let students = [{
name: "Milla Jovovich",
track: "Fullstack JavaScript",
achievements: 5,
points: 50
},
{
name: "Bjon Aarseth",
track: "iOS Development",
achievements: 7,
points: 70
},
{
name: "Varg Oystein",
track: "Front End Development",
achievements: 12,
points: 120
},
{
name: "Wilhelm Striepe",
track: "Software Engineering",
achievements: 9,
points: 90
},
{
name: "Anders Hansen",
track: "Data Science",
achievements: 22,
points: 220
}
];
let message = "";
let student;
let search;
function print(message) {
let outputDiv = document.getElementById("output");
outputDiv.innerHTML = message;
}
message = ""; //declare your "message" here, the content of output
students.forEach(function(myElement) {
message += "<h2>Student: " + myElement.name + "</h2>";
message += "<p>Track: " + myElement.track + "</p>";
message += "<p>Achievements: " + myElement.achivements + "</p>";
message += "<p>Points: " + myElement.points + "</p>";
});
print(message); // print "message" when all students have been added to the variable
<div id="output"></div>

Related

How to change value of global variable inside function

I know this has been asked before, but my case seems to be little bit different
I have two js files, one for logic, one for objects which includes data about movie(s)
my first file looks like this
var movieTitle = document.getElementById("movieTitle");
var rating = document.getElementById("rating");
var movieYear = document.getElementById("movieYear");
var movieDuration = document.getElementById("movieDuration");
var actorName = document.getElementById("actorName");
var actorRole = document.getElementById("actorRole");
var actorNameI = document.getElementById("actorName2");
var actorRoleII = document.getElementById("actorRole2");
var testClick = document.getElementById("testClick");
var movie = movieI;
movieTitle.innerHTML = "Title: " + movie.title;
movieYear.innerHTML = "release Year: " + movie.releaseYear;
movieDuration.innerHTML = "Duration: " + movie.duration;
actorName.innerHTML = "Name: " + movie.actors[0].name;
actorRole.innerHTML = "Role: " + movie.actors[0].role;
actorNameI.innerHTML = "Name: " + movie.actors[1].name;
actorRoleII.innerHTML = "Role: " + movie.actors[1].role;
rating.innerHTML = "Rating: " + movie.rating;
testClick.addEventListener("click", function(){
var movie = movieII
})
file from where i fetch objects looks like this
var movieI = {
title: "Titanic",
releaseYear: 1997,
rating: "PG21",
duration: "3 hours",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "kate winslet",
role: "role goes here"
},
]
};
var movieII = {
title: "Wolf of wall street",
releaseYear: 2013,
rating: "PG18",
duration: "2H 30M",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "jonah hill",
role: "role goes here"
},
]
};
on my first js file i have following function
testClick.addEventListener("click", function(){
movie = movieII
})
this is supposed to modify value of movie variable and set it to movieII so it can switch/access second object(movieII) from my objects file, but it does not seem to be working.
Your problem is that updating the object doesn't change what has already been shown in the HTML, you need to update your HTML with the new information but only after it changed in the variable.
You can do that linear ( as you have in your code) or just creating a function that you can call every time and will help you avoiding duplicated code.
Here is one way you can do that:
//Titanic
let movieI = {
title: "Titanic",
releaseYear: 1997,
rating: "PG21",
duration: "3 hours",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "kate winslet",
role: "role goes here"
},
]
};
let movieII = {
title: "Wolf of wall street",
releaseYear: 2013,
rating: "PG18",
duration: "2H 30M",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "jonah hill",
role: "role goes here"
},
]
};
let actorsBox = document.getElementById("actos-box");
let movieTitle = document.getElementById("movieTitle");
let rating = document.getElementById("rating");
let movieYear = document.getElementById("movieYear");
let movieDuration = document.getElementById("movieDuration");
let actorName = document.getElementById("actorName");
let actorRole = document.getElementById("actorRole");
let actorNameI = document.getElementById("actorName2");
let actorRoleII = document.getElementById("actorRole2");
let testClick = document.getElementById("testClick");
let movie = movieI;
updateMovie();
testClick.addEventListener("click", function(){
movie = movieII
updateMovie();
})
function updateMovie(){
movieTitle.innerHTML = "Title: " + movie.title;
movieYear.innerHTML = "release Year: " + movie.releaseYear;
movieDuration.innerHTML = "Duration: " + movie.duration;
actorName.innerHTML = "Name: " + movie.actors[0].name;
actorRole.innerHTML = "Role: " + movie.actors[0].role;
actorNameI.innerHTML = "Name: " + movie.actors[1].name;
actorRoleII.innerHTML = "Role: " + movie.actors[1].role;
rating.innerHTML = "Rating: " + movie.rating;
}
Also I highly recommend you not to use var as it can do weird things you might not want to do.
Take a look at this for learning more about let variables.
Have you try to use function and parameters for this project?
Here was the docs
Function in js

How can i display massages based on the user who sent and received the message

I don't know what's wrong with my code am not getting the intended output. Anybody to lend a helping hand and I'll really appreciate it.
If append the row class inside the for loop am getting all the messages but you can't differentiate who sent and who received and when I append the class outside the for loop am only getting one message.
xhr.onload = function () {
var messages = [
{ id: 36, message: "hay here", username: null, senderId: 1, receiverId: 9 },
{ id: 38, message: "hay there again", username: null, senderId: 1, receiverId: 9 },
{ id: 37, message: "yes hay", username: null, senderId: 9, receiverId: 1 },
];
var rowClass = "";
for (var message = 0; message < messages.length; message++) {
if (messages[message].senderId === messages[message].senderId) {
rowClass =
'<div style="text-align:right">' +
'<p style="background-color:lightblue">' +
mymessages[message].message +
"</p>" +
"<div>";
} else {
rowClass =
'<div style="text-align:left">' + '<p style="background-color:green">';
messages[message].message;
"</p>" + "<div>";
}
}
$(".message").append(rowClass);
};
You need to check whether the current user's id is same as that of the message, for example:
const currentUserId = 9;
var messages = [
{ id: 36, message: "hay here", username: null, senderId: 1, receiverId: 9 },
{ id: 38, message: "hay there again", username: null, senderId: 1, receiverId: 9 },
{ id: 37, message: "yes hay", username: null, senderId: 9, receiverId: 1 },
];
var rowClass = "";
for (var message = 0; message < messages.length; message++) {
if (messages[message].senderId === currentUserId) {
rowClass +=
'<div style="text-align:right">' +
'<p style="background-color:lightblue">' +
messages[message].message +
"</p>" +
"<div>";
} else {
rowClass +=
'<div style="text-align:left">' +
'<p style="background-color:green">' +
messages[message].message +
"</p>" +
"<div>";
}
}
$(".message").append(rowClass);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="message"></div>

How to properly check if a name is available in an array made of objects (record collection)?

so my plan for this was to have a message appear asking someone to type in a student name. Javascript would look through a record, which is in a seperate JS file, and then output that in the message variable. If suppose the student didn't exist, the output message would be the alert box in the else statement.
Heres a record of the students:
var students=[
{
name:'Chris',
track:'IOS',
achievements:'100',
points:'1000'
},
{
name:'John',
track:'Web Design',
achievements:'90',
points:'1000'
},
{
name:'Brent',
track:'Front-End',
achievements:'70',
points:'1000'
},
{
name:'Josh',
track:'Full-Stack',
achievements:80,
points:'1000'
},
{
name:'Nick',
track:'AI',
achievements:'60',
points:'1000'
}
];
var message="";
var search=prompt("Type name of student");
while (search!=="quit") {
for (var i=0; i<students.length; i+=1) {
var studentName=students[i].name;
if (studentName===search) {
message+="<h1>"+studentName+"</h1>";
message+="<p>"+student[i].track+"</p>";
message+="<p>"+student[i].achievements+"</p>";
message+="<p>"+student[i].points+"</p>";
break;
} else {
alert("That student does not exist. Try again");
break;
}
}
search=prompt("Type name of student");
}
print(message);
When I try this code, it asks me for the student's name and then says he/she is not available. Apparently, the determination that the student is not in the list should only be made after the loop has finished checking all the students. Then, and only if nothing was found, should the failure message be output.
The problem for me, conceptually, is that the final value of the variable, studentName, after the for loop ends will be the name property of the last object in the array. So how would I redesign my for loop then?
How can I redesign my code to accomplish just that?
You can try this,
var message="";
var search=prompt("Type name of student");
while (search!=="quit") {
// we will get result if any one student name matches
var result = students.find((student) => student.name === search);
if (result) {
message+="<h1>"+result.name+"</h1>";
message+="<p>"+result.track+"</p>";
message+="<p>"+result.achievements+"</p>";
message+="<p>"+result.points+"</p>";
}
else {
alert("That student does not exist. Try again");
}
search=prompt("Type name of student");
}
print(message);
you can filter your list first and then check it like
const students = [
{
name: 'Chris',
track: 'IOS',
achievements: '100',
points: '1000'
},
{
name: 'John',
track: 'Web Design',
achievements: '90',
points: '1000'
},
{
name: 'Brent',
track: 'Front-End',
achievements: '70',
points: '1000'
},
{
name: 'Josh',
track: 'Full-Stack',
achievements: 80,
points: '1000'
},
{
name: 'Nick',
track: 'AI',
achievements: '60',
points: '1000'
}
];
let search = prompt('Type name of student');
while (search !== 'quit') {
const filteredList = students.filter(function(student) {
return student.name === search;
});
let message = '';
if (filteredList.length > 0) {
for (const student of filteredList) {
message += '<h1>' + student.name + '</h1>';
message += '<p>' + student.track + '</p>';
message += '<p>' + student.achievements + '</p>';
message += '<p>' + student.points + '</p>';
}
alert(message);
} else {
alert('That student does not exist. Try again');
}
search = prompt('Type name of student');
}
In order to avoid looping through the entire array each time you want to show a message for the user, making an object from the array is the best approach.
for example:
var students=[
{
id: 1,
name:'Chris',
track:'IOS',
achievements:'100',
points:'1000'
},
{
id: 2,
name:'John',
track:'Web Design',
achievements:'90',
points:'1000'
},
{
id: 3,
name:'Brent',
track:'Front-End',
achievements:'70',
points:'1000'
},
{
id: 4,
name:'Josh',
track:'Full-Stack',
achievements:80,
points:'1000'
},
{
id: 5,
name:'Nick',
track:'AI',
achievements:'60',
points:'1000'
}
];
const arrayToObject = (array) =>
array.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {});
const studentsObject = arrayToObject(students);
console.log(studentsObject);
console.log(studentsObject[2]);

print an array of objects in javascript

Hello I need help accessing elements of objects in my JavaScript
What's the error of this one
var people = [
{
name: "Jake",
age: 20
},
{
name: "John",
age: 23
},
{
name: "Mike",
age: 21
},
]
for (var i=0; i < 3 ;i++)
document.getElementById("myDiv").innerHTML += "Name: " + people[i].name + "Age: "+ people[i].age +"\n";
I only need to write to the div the values of the array of objects
There was nothing wrong with your Javascript. Check if you have written everything correct for myDiv. Here is my example and it worked fine.
Remember to put a <br> tag instead of \n and " Age: " instead of "Age: ". Good luck!
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div id="myDiv">
<div>
</body>
</html>
<script>
var people = [
{
name: "Jake",
age: 20
},
{
name: "John",
age: 23
},
{
name: "Mike",
age: 21
},
]
for (var i=0; i < 3 ;i++)
document.getElementById("myDiv").innerHTML += "Name: " + people[i].name + " Age: "+ people[i].age + "<br>";
</script>

Parse Database JavaScript and PhoneGap

I've been working on an restaurant app that should get the menu from an online database.
This is how I currently and "Manually" populate the menu:
Controller.html
$scope.menu = [{
name: 'Espresso',
price: 27,
qty: 1,
desc: "One shot of espresso prepared with 7 grams of ground coffee in a single portafilter. The shot should be 1 ounce of liquid. You have two choices with espresso: ristretto, a very short or “restrained” shot, brewed at less than 2/3 of a demitasse, or luongo, a long pull of espresso brewed so the liquid should be more than 2/3 of a demitasse.",
img: "img/espresso.png",
active: false,
sizes: [{name: "Small", price: 0, active:false},
{name: "Medium", price: 5, active:false},
{name: "Large", price: 10, active:false}],
flavors: [{name: 'Vanilla', price: 8, active: false},
{name: 'Almond', price: 8, active: false},
{name: 'Hazelnut', price: 8, active: false},
{name: 'Caramel', price: 8, active: false}]
}];
However I can't seem to achieve populating this using Parse, how would I approach this using a query as the following (Which is a working query).
Index.html
<script type="text/javascript">
Parse.initialize("vGoJDvwwfZBiUFcwfkee7M5vCqL7lLxCgKIFJXDc", "6VRlos6qppaek1uDPPLqpHtmB3fHefOJMqYJNxj9");
var DrinkMenu = Parse.Object.extend("DrinkMenu");
var query = new Parse.Query(DrinkMenu);
query.find({
success: function(results) {
alert("Successfully retrieved " + results.length + " items.");
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
alert(object.id + ' - ' + object.get('name'));
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
</script>
You can notice I can get the variables needed for each item, in this case the name of the first result, which I display in an alert.
Any help is appreciated!
After Parse.initialize, create a variable, like this:
var arrMenu = [];
then change the line alert(object.id + ' - ' + object.get('name')); to
arrMenu.push({
name: object.get('name'),
price: object.get('price'),
qty: object.get('qty'),
desc: object.get('desc'),
img: object.get('img'),
active: object.get('active'),
sizes: object.get('sizes'),
flavors: object.get('flavor')
});
I am supposing that you are storing the info in the Parse Collection with the structure you mentioned. If it is different, let me know.
And, after the brack the closes the for, you add:
$scope.menu = arrMenu;
I hope it helps!

Categories

Resources