How to change value of global variable inside function - javascript

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

Related

Global Count Variable not increasing

For some reason, I cannot get my global variable counter to increase, even when it increases within the function I have the count++ occurring in. My outputted results are different between the text outputted within the function and the text outside of it. Any idea what I am doing wrong here? Shouldn't the count increase on each iteration of the survey.oncomplete function results?
Survey
.StylesManager
.applyTheme("modern");
var kn2 = "LwrHXqFRN_pszCopTKHF_Q"
var kn3 = "exroCUoYl4wVzs7pKU_49w"
var count = 0
var keyname = ("kn" + count)
var mapilink = "https://images.mapillary.com/" + (keyname) + "/thumb-1024.jpg";
var json = {
pages: [
{
name: "page1",
elements: [
{
type: "image",
name: "image",
imageLink: (mapilink),
imageHeight: 580,
imageWidth: 640
},
{
type: "html",
name: (keyname),
visible: false,
html: (keyname)
},
{
type: "rating",
name: "Walkability",
title: "How walkable does this look to you"
},
{
type: "rating",
name: "Saftey",
title: "How safe does this look to you"
},
{
type: "rating",
name: "Comfortability",
title: "How comfortable does this look to you"
}
]
}
]
}
window.survey = new Survey.Model(json);
var username = document.getElementById("user").value;
survey
.onComplete
.add(function (result) {
count ++;
var PID = document.getElementById("user").value;
var results = PID + "_" + (keyname) + ":\n" + JSON.stringify(result.data, null, 3) + (count) ;
document
.querySelector('#surveyResult')
.textContent = results;
survey.clear();
survey.render();
});
$("#surveyElement").Survey({model: survey});
Got an answer from a seperate stackexchange post - basically, I needed to wrap everything in more functions.
function outputting function text rather than expected output

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]);

Using forEach() on an Array of Objects

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>

Multiple object array not working in At.js

I'm using At.js plugin. It's working fine for a single object (demo)
var names1 = ["Jacob", "Isabella", "Ethan", "Emma", "Daniel", "Madison"];
var names = $.map(names1, function(value, i) {
return {
'id': i,
'name': value,
'email': value + '#yahoo.com'
};
});
But when I try to add multiple objects it's not working (demo). I knew the code is the problem.
I want to display the description when a user selects the name of the person using # tag.
$(function() {
$.fn.atwho.debug = true
var names1 = [{
"name": "Jacob",
"description": "description one description one description one"
},
{
"name": "Isabella",
"description": "description two description two description two"
}
];
var names = $.map(names1, function(value, description, i) {
return {
'id': i,
'name': value,
'email': description
};
});
var at_config = {
at: "#",
data: names,
headerTpl: '<div class="atwho-header">Service List <small>↑ ↓ </small></div>',
insertTpl: '${email}',
displayTpl: "<li>${name}</li>",
limit: 200
}
$inputor = $('#inputor').atwho(at_config);
$inputor.caret('pos', 47);
$inputor.focus().atwho('run');
});
The map function in Jquery does not take each element in a object as the function argument, you get the entire object (the element in the list) and you then need to extract the name, and the description. You were almost there.
$(function() {
$.fn.atwho.debug = true
var names1 = [{
"name": "Jacob",
"description": "description one description one description one"
},
{
"name": "Isabella",
"description": "description two description two description two"
}
];
var names = $.map(names1, function(value, index) { //Here I have only used value
return {
'id': index,
'name': value.name, //Here I take value.name from the object
'email': value.description //And value.description from the object
};
});
var at_config = {
at: "#",
data: names,
headerTpl: '<div class="atwho-header">Service List <small>↑ ↓ </small></div>',
insertTpl: '${email}',
displayTpl: "<li>${name}</li>",
limit: 200
}
$inputor = $('#inputor').atwho(at_config);
$inputor.caret('pos', 47);
$inputor.focus().atwho('run');
});

How would I each through dynamic content and append something if a value = false?

I'm trying to iterate over some JSON that I have included in my file and everything seems to be working fine up until I want to add my icons into each stakebox icon div. Any idea what might be going wrong? I want to add one icon if the value of my JSON object === true and one if the value === false.
$.each(stakeBox, function (i, stakeBoxData) {
var jsonDate = stakeBoxData.data_change_date;
var winLoss = stakeBoxData.win;
var points = stakeBoxData.amount_stakebox;
var winLoss = stakeBoxData.win;
var id = stakeBoxData.id;
if (stakeBoxDay < jsonDate) {
var self = $(this);
console.log(this.win);
$('.stakebox-container').append('\
<div id="' + id + '" class="stakebox-message-container">\
<div id="stakebox-icon"></div>\
<div><h5 id="stakebox-game"></h5></div>\
<div><h5 id="stakebox-points">' + points + '</h5></div>\
</div>\
');
if (this.win === true) {
$('#stakebox-icon').append('<i class="far fa-smile face"></i>');
} else {
$('.stakebox-message-container').css('background', '#a20000');
$('#stakebox-icon').append('<i class="far fa-frown face"></i>');
};
// console.log(i);
} else {
// console.log('nope');
}
});
Here is some of the JSON for reference:
var stakeBox = [{
id: "1",
amount: "40.00",
user_id: "1",
amount_stakebox: "33",
win: true,
data_change_date: "20180229",
username: "bkessler",
game_id: "1380",
team_id: "791",
status: "1"
}, {
id: "2",
amount: "1.00",
user_id: "1",
amount_stakebox: "4124124",
win: false,
data_change_date: "20180429",
username: "bkessler",
game_id: "1380",
team_id: "791",
status: "1"
}];

Categories

Resources