Javascript object returns undefined - javascript

var movies =
[
{name: "In Bruges", rating:"4.7", seen:false},
{name: "Frozen", rating: "4.5", seen:true},
{name: "Lion King", rating:"5", seen:true},
]
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies.seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies.name + "\" - ";
result += movies.rating + " stars"
console.log(result)
};
You have not seen "undefined" - undefined stars is the result in chrome however you should see You have seen/not seen "movie name" - "rating" stars.
I need to use for loop to print out what each movie I have watched and rating and if I have seen it or not. Question is why is it undefined? Should the code see movies.rating and just substitute the value there? Can some one check my code and help me with my for loop?

movies is an array movies.seen won't work use movies[i].seen and like wise for other properties

Change movies.seen, movies.rating and movies.name to movies[i].seen, movies[i].rating, and movies[i].name.

Use index to access item of array; e.g. movies[i]:
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies[i].seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies[i].name + "\" - ";
result += movies[i].rating + " stars"
console.log(result)
}
Or you could store the array item in a variable and use it like this:
for (var i = 0; i < movies.length; i++) {
var movie = movies[i];
var result = "You have ";
if (movie.seen) {
result += "watched ";
}
else {
result += "not seen ";
}
result += '"' + movie.name + '" - ';
result += movie.rating + " stars";
console.log(result);
}

Here is a working Plunker for you to see it working. :)
var movies =
[
{name: "In Bruges", rating:"4.7", seen:false},
{name: "Frozen", rating: "4.5", seen:true},
{name: "Lion King", rating:"5", seen:true},
]
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies[i].seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies[i].name + "\" - ";
result += movies[i].rating + " stars"
alert(result)
}
You were trying to access properties of movies called seem, name and rating, but movies has 3 objects indexed from 0 to 2.

You are using movies inside loop and movies do not contain those properties.
And it is allways safe to use forEach loop while iterating arrays
Do something like
movies.forEach(function(movie){
var result = "You have ";
if(movie.seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += movie.name + " - ";
result += movie.rating + " stars";
console.log(result);
});

I suggest to use a little other approach to iterate over the array and for the check if a movie has been seen.
var movies = [
{ name: "In Bruges", rating: "4.7", seen: false },
{ name: "Frozen", rating: "4.5", seen: true },
{ name: "Lion King", rating: "5", seen: true },
];
movies.forEach(function (movie) {
var result = "You have ";
result += movie.seen ? "watched " : "not seen ";
result += "\"" + movie.name + "\" - ";
result += movie.rating + " stars"
document.write(result + '<br>');
});

Related

How to serializeObject with nested object in javascript?

I have
"resource_ratio": [
[
"Barbara",
"Ben",
"Anne",
"John",
"Cindy",
"Nick",
"Lex",
"Edd",
"Eric",
"Jacky",
"Paul"
],
[
0.11974110032362459,
0.037756202804746494,
0.23516720604099245,
0.10895361380798274,
0.10140237324703344,
0.03559870550161812,
0.02912621359223301,
0.08737864077669903,
0.02481121898597627,
0.1186623516720604,
0.10140237324703344
]
]
this 2 dim array that I want to display on HTML page using javascript
and then get the result back in JSON from after clicking a button.
For now, I displayed the values of resource_raio using this
var resourceRatioBoxTag = new Array();
var resourceRatioTag = new Array();
for (var i = 0; i < selectedData.resource_ratio.length; i++) {
//selectedData.resource_ratio[1][0]
resourceRatioBoxTag[i] = "<input id='resourceRatio[" + i + "]' name='resourceRatio'>";
for (var j = 0; j < selectedData.resource_ratio[i].length; j++) {
resourceRatioBoxTag[i] += "<input type='text' id='resourceRatio[" + i + "][" + j + "]' value='" + selectedData.resource_ratio[i][j] + "' name='" + i + "'>";
}
resourceRatioBoxTag[i] += "</input>";
$("#resourceRatioDiv").append(resourceRatioBoxTag[i]);
}
which gave me result of one single array with all the values inside like [val1, val2, val3]
And when I do
var dataBox = $('#inputDataForm').serializeObject();
the JSON result
It's not in form of
"resource_ratio": [
[
"Barbara",
"Ben",
"Anne",
"John",
"Cindy",
"Nick",
"Lex",
"Edd",
"Eric",
"Jacky",
"Paul"
],
[
0.11974110032362459,
0.037756202804746494,
0.23516720604099245,
0.10895361380798274,
0.10140237324703344,
0.03559870550161812,
0.02912621359223301,
0.08737864077669903,
0.02481121898597627,
0.1186623516720604,
0.10140237324703344
]
]
as I wanted it to be. So I've tried changing the name of the input of array values (Since I've learned that SerializeObject group values by the name of input) and made something like this
for (var i = 0; i < selectedData.resource_ratio.length; i++) {
//selectedData.resource_ratio[1][0]
resourceRatioBoxTag[i] = "<p id='resourceRatio[" + i + "]' name='resourceRatio'>";
for (var j = 0; j < selectedData.resource_ratio[i].length; j++) {
resourceRatioBoxTag[i] += "<input type='text' id='resourceRatio[" + i + "][" + j + "]' value='" + selectedData.resource_ratio[i][j] + "' name='" + i + "'>";
}
resourceRatioBoxTag[i] += "</p>";
$("#resourceRatioDiv").append(resourceRatioBoxTag[i]);
}
(Its the same code except I changed the p tag to input tag]
which gave me serialized values of
"0": [
"Barbara",
"Ben",
"Anne",
"John",
"Cindy",
"Nick",
"Lex",
"Edd",
"Eric",
"Jacky",
"Paul"
],
"1": [
"0.11974110032362459",
"0.037756202804746494",
"0.23516720604099245",
"0.10895361380798274",
"0.10140237324703344",
"0.03559870550161812",
"0.02912621359223301",
"0.08737864077669903",
"0.02481121898597627",
"0.1186623516720604",
"0.10140237324703344"
]
which is ALMOST same as how I want it to be, except it's not INSIDE the resource_ratio values, it's grouped by [0] and [1] (following by the input name).
What should I do to get my resourceRatio[i][j] values inside [i] which is inside the resourceRatio key? I'm sorry if my question is so confusing
the serializeObject is a plug in of jquery I used. It's this:
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
The easiest way to convert a value to JSON is to use JSON.stringify:
let dataAsString = JSON.stringify( myObject )
This will break if your object has any circular references. That won't be a problem if your data is a typical piece of business data.
And then to convert it back:
let data = JSON.parse( dataAsString )
Unless you have a very special reason for doing so, I'd recommend that you always use this built-in capability instead of something from a library like jQuery.

JSON parse variable result

I have a JSON which I query with xhr. The objects (person) contain a key-value pair called "serviceLevel" that I have to split.
When I stack this in a variable (services) and log it like this:
let main = document.getElementsByTagName('main');
getXHR("GET", './db/orga.json', (success) => {
format(success)
}, (error) => {
console.error(error)
});
function format() {
let people = arguments[0];
for (let i in people) {
let person = people[i];
let services = person.serviceLevel.split(".");
console.log(services);
console.log(person.serviceLevel.split("."));
let idCard = document.createElement('div');
idCard.id = person.firstName + person.familyName;
idCard.classList.add('person');
idCard.innerHTML = "<div class=\"item nom\"><span class=\"prenom\">" + person.firstName + "</span><span class=\"famille\">" + person.familyName + "</span></div>";
idCard.innerHTML += "<span class=\"job\">" + person.jobTitle_1 + "</span>";
idCard.innerHTML += "<span class=\"mail\"><a href=\"mailto:" + person.mail + "\">" + person.mail + "</span>";
idCard.innerHTML += "<span class=\"tel\"><a href=\"tel:" + person.phone_1 + "\">" + person.phone_1 + "</span>";
idCard.innerHTML += "<span class=\"tel\"><a href=\"tel:" + person.mobile + "\">" + person.mobile + "</span>";
for (let j in services) {
let serviceElement = document.getElementById(services[j]);
if (!serviceElement) {
let serviceElement = document.createElement('div');
serviceElement.id = services[j];
serviceElement.classList.add('n' + j, "service");
serviceElement.innerHTML = "<span class=\"title\">" + services[j] + "</span>";
if (j == 0) {
if (services[services.length - 1] = j) {
serviceElement.appendChild(idCard);
main[0].appendChild(serviceElement);
}
} else {
let parent = services[j - 1],
parentService = document.getElementById(parent);
if (services[services.length - 1] = j) {
serviceElement.appendChild(idCard);
}
parentService.appendChild(serviceElement);
}
} else {
serviceElement.appendChild(idCard);
}
}
}
}
const data = [{
"Tri": "blablablabla, CSMSI.SAFS, n, XXXX, YYYY",
"Department": "The best department",
"serviceLevel": "CSMSI.SAFS",
"organisationLevel": "blablablabla",
"rang": "n",
"familyName": "XXXX",
"firstName": "YYYY",
"jobTitle_2": "Directeur",
"jobTitle_1": "Directeur",
"phone_1": "nn nn nn nn nn",
"phone_2": "",
"mobile": "nn nn nn nn nn",
"mail": "xxxx.yyyy#zzzz.fr",
"location": "france"
}];
format(data);
The results are different:
(2) ["CSMSI", "SAFS"]
0: "CSMSI"
1: "SAFS"
length: 2
(2) ["CSMSI", "SAFS"]
0: "CSMSI"
1: "1"
length: 2
As we can see, content of "services" are good, but when I extend the tree, the value of the second key value is "1" ... which is a problem. Is there a way to change this?
when I use a for loop with "classical" (i = 0; i < people.length; i++), i don't have the problem....

Looping over JavaScript object and adding string to end if not the last item

{
field_country: ["England", "Netherlands", "India", "Italy"],
field_continent: ["Europe"],
field_group: ["Building", "People", "Landscape"
}
I want to loop over each item and return the key and the array together with ending 'OR' for example:
field_country: "England" OR field_country: "Netherlands"
The last item should not end with 'OR' in the loop. I am not sure what the best process is for this using vanilla JS. So far my code is as follows:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i == 1) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I would be very grateful for any assistance.
Thanks in advance.
You can do something like this with Object.entries and Array.reduce if you would like to get the final result in the form of an object:
const data = { field_country: ["England", "Netherlands", "India", "Italy"], field_continent: ["Europe"], field_group: ["Building", "People", "Landscape"] }
const result = Object.entries(data).reduce((r, [k, v]) => {
r[k] = v.join(' OR ')
return r
}, {})
console.log(result)
It is somewhat unclear what is the final format you need to result in but that should help you to get the idea. If ES6 is not an option you can convert this to:
const result = Object.entries(data).reduce(function(r, [k, v]) {
r[k] = v.join(' OR ')
return r
}, {})
So there are is no arrow function etc.
The idea is to get the arrays into the arrays of strings and use the Array.join to do the "replacement" for you via join(' OR ')
Here's the idea. In your code you are appending " or " at the end of your strings starting at index 0. I suggest you append it at the the beginning starting at index 1.
var somewords = ["ORANGE", "GREEN", "BLUE", "WHITE" ];
var retval = somewords[0];
for(var i = 1; i< somewords.length; i++)
{
retval += " or " + somewords[i];
}
console.log(retval);
//result is: ORANGE or GREEN or BLUE or WHITE
Your conditional expression if (i == 1) would only trigger on the second iteration of the loop since i will only equal 1 one time.
Try something like:
if (i < (facetResults.length - 1)) {
// only add OR if this isn't the last element of the array
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
}
Here's your updated code:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i < (facetResults.length - 1)) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});

how to get an alert message if the value entered is not found in the array in javascript

I have an array of objects and I'm able to loop through the array using a for loop and I can print it to the page without problems if the value is found, but I'm trying to get an alert message to display if the value is not found and continue asking for the next value until the user types quit. The problems with my code is that the alert message keeps appearing until the loops ends if the value is not found. Here's my code:
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
} else{
alert(look + ' was not found');
}
}
print(message);
}
while (true){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search === null || search === 'quit'){
break;
}
findStudent(search);
}
Any help is appreciated. Thanks.
i think it could be help full for you https://codepen.io/kalaiselvan/pen/YQGbar
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
var flag=0;
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
flag=0;
break;
} else{
flag=1;
}
}
if(flag==1){
alert(look + ' was not found');
showprompt();
}
}
function showprompt(){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search != null && search !== "quit"){
findStudent(search);
}
}
showprompt();
Lets explain this part of code:
function findStudent( look ) {
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
} else{
alert(look + ' was not found');
}
}
print(message);
}
What that does is it loops with a for loop over an array/object and prints a message or alerts for every record inside the array. That is the problem. You only want to check if the value is found and print or alert if so.
function findStudent( look ) {
var found = false;
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
found = true;
break; // if the student is found no need to loop further
// move on with rest of code
}
}
// so if the student was found in the for loop, found will be true
// else found will be false cause we set it to false at the beginning
if(found) {
message += getStudentReport( student );
print(message);
} else {
alert(look + ' was not found');
}
}
you can use indexof
https://www.w3schools.com/jsref/jsref_indexof_array.asp
else if (students.indexOf(look) == -1){
alert(look + ' was not found');
})
You need to stop the loop inside findStudent() function.
First, add a boolean varible: var flag = true;
Second, use it as condition of while loop: while(flag){...}
Finally, assign flag = falsewhenever want to stop the loop:
function findStudent( look ){
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport( student );
print(message);
//possible stop here if you want
flag = false;
} else{
alert(look + ' was not found');
//possible stop here if you want
flag = false;
}
}
print(message);
//possible stop here if you want
flag = false;
}
var message = '';
var student;
var search;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function getStudentReport( student ) {
var report = '<h2>Student: ' + student.name + '</h2>';
report += '<p>Track: ' + student.track + '</p>';
report += '<p>Points: ' + student.points + '</p>';
report += '<p>Achievements: ' + student.achievements + '</p>';
return report;
}
function findStudent( look ){
message = '';
for (var i = 0; i < students.length; i += 1) {
student = students[i];
if (look === student.name) {
message += getStudentReport(student);
}
}
return message;
}
while (true){
search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
if (search === null || search === 'quit'){
break;
}
if(findStudent(search)){
print(findPurpose(search));
break;
} else {
alert(search + ' was not found');
}
}

How to handle an dynamic array?

I want to show up the names of the members of an array "path" in my console.
console.log("start: ", path[0].name, "second: ", path[1].name, "third: ", path[2]name, ....)
But the problem is, that my array always changes it's size (clicking algorithm), that means sometimes it has the lenght 4 or sometimes 8 ect.
How can i adjust the console.log code to this dynamic array?
Thanks so much!
Try
path.forEach((each, i)=>{
console.log ("item" + i+ ':' + each.name );
})
Something like this:
var path = ['Prit', 'Bab', 'Nav']
var item = ["first","second", "third"];
for (i = 0; i < path.length;i++){
console.log(item[i] + ":" + path[i])
}
Try something like this for single line result set ...
var result = "";
for (var i = 0, len = path.length; i < len; i++) {
if (i !== 0) {
result += ", ";
}
result += (i + 1) + ": " + path[i].name;
}
console.log(result);
you could use a for loop here , ie,
for (var i=0;i<path.length;i++) {
console.log("item no "+ i +": " + path[i]);
}
/* Console Array */
var consoleArray = new Array;
/* Names */
var path = [
{name: 'bob'},
{name: 'jimmy'},
{name: 'chris'},
{name: 'alexander'},
{name: 'mark'}
];
/* Loop */
for(var i = 0; i < path.length; i++) {
consoleArray.push((i + 1) + ': ' + path[i].name);
}
/* Console Log */
console.log(consoleArray.join("\n"));
With ES6, you could use spread syntax ....
var path = [{ name: 'Jo'}, { name: 'John'}, { name: 'Jane'}];
console.log(...path.map((a, i) => (i ? i + 1 : 'Start') + ': ' + a.name));

Categories

Resources