Unexpected behaviour of FOR loop in Angular app - javascript

This is most probably a silly mistake but I can't see the issue. I'm trying to create an array of objects for an image gallery in my Angularjs app. Each photo object has a thumb and img attribute. The for loop is creating the objects fine and I'm logging each to the console to check them:
{thumb: "/10000/0_t.jpg", img: "/10000/0_l.jpg"}
{thumb: "/10000/1_t.jpg", img: "/10000/1_l.jpg"}
{thumb: "/10000/2_t.jpg", img: "/10000/2_l.jpg"}
...
However, after running this code:
var images = [];
var image = {};
for (var i = 0; i < property.images.length; i++) {
image.thumb = "/" + property.id + "/" + i + "_t.jpg";
image.img = "/" + property.id + "/" + i + "_l.jpg";
console.log(image); //this gives expected output
images.push(image);
};
console.log(images); //this gives all entries as the same
the final console.log gives me:
{thumb: "/10000/27_t.jpg", img: "/10000/27_l.jpg"} //X28
for each image. The 27 comes from the fact that there are 28 images but I can't understand why they all have the same paths?

You need to make a new object on each iteration:
var image;
for (var i = 0; i < property.images.length; i++) {
image = {};
image.thumb = "/" + property.id + "/" + i + "_t.jpg";
image.img = "/" + property.id + "/" + i + "_l.jpg";
console.log(image); //this gives expected output
images.push(image);
};
If you don't, then each iteration will re-use that same original object. Passing an object to .push() does not make a copy.

how about this:
var path = "/" + property.id + "/";
var images = property.images.map((img,i)=>{
return {
thumb: path + i + "_t.jpg",
img: path + i + "_l.jpg"
}
});
console.log(images);

Works just fine for me. Please, limit your scope as much as possible in JavaScript.
Refer to chapter 16 Introducing a New Scope via an IIFE in the book; Speaking JavaScript.
Note: An IIFE is an "immediately invoked function expression."
var property = {
id : 10000,
images: [{ id: 1 }, { id: 2 }, { id: 3 }]
};
var images = [];
for (var i = 0; i < property.images.length; i++) {
(function(){
var image = {}; // This should be inside the loop.
// This way the scope does not leak.
image.thumb = "/" + property.id + "/" + i + "_t.jpg";
image.img = "/" + property.id + "/" + i + "_l.jpg";
images.push(image);
}());
};
document.body.innerHTML = '<pre>' + JSON.stringify(images, null, 4) + '</pre>';

Related

HTML Javascript ArrayList

function saveForm() {
var array = [];
array.push(txtTName.value + "," + txtTNumber.value + "," + txtProjName.value + "," + getTotal());
var scores = document.getElementById("scores");
scores.innerHTML += "<br \>" + array[0] + array[1] + array[2];
}
Here's my code. So when a button is pushed it calls "saveForm()" which saves the values into an array and displays them. The first time its called it displays "xxxxx undefined undefined" the next time it calls "yyyyyy undefined undefined". Shouldn't it be returning "xxxxx yyyyy undefined"?
I'm only displaying elements 0,1, and 2 right now for testing purposes.
function saveForm(){
var array = [];
var list = txtTName.value + "," + txtTNumber.value + "," + txtProjName.value + "," + getTotal();
array.push(list);
var scores = document.getElementById("scores");
scores.innerHTML += "<br \>" + array[0] + array[1] + array[2];
}
Here's an edited version of saveForm(). The values don't really matter, I'm more wondering if there's a reason its only changing the first element. Do I need to create array outside of the function?
function saveForm() {
var array = [];
array.push(txtTNumber.value);
array.push(txtTNumber.value);
array.push(txtProjName.value);
array.push(getTotal());
document.getElementById("scores").innerHTML += "<br \>" + array.join(', ');
}
var array = [];
function saveForm(){
....
}

Get Text information sort and number them an put ";" after number and after each block

Again some Problems.
I' get some values of a Textfield ,shown like them:
134.45 987.46 -89.10
224.67 127.26 -19.12
764.32 187.96 -78.25
...and so on...
I'm get them with
function LineWriteToNp01() {
var getNP01TableData = $('#null_tabelle_dues1_text').text();
}
i need them in
1;134.45;987.46;-89.10< br /><<< yes also the break - it will written in a .TXT file >>>
2;224.67;127.26;-19.12< br />
3;764.32;187.96;-78.25< br />
...and so on...
I couldn't figure it out how to. seems insoluble :(
The hekp from "guest271314" was perfekt. i've built it a Little more dynamic.
function LineWriteToNp01() {
var getNP01TableData = $('#null_tabelle_dues1_text').text().replace(/\s+X/, "");
var arr = getNP01TableData.split(/\s+/);
var _arr = [];
var index = 1;
for (var i = 1; i <= (arr.length-1)/3; i++) {
_arr.push( i + ";" + arr[index] + ";" + arr[index + 1] + ";" + arr[index + 2] + "<br />\n");
index = index + 3;
}
_arr = _arr.toString().replace(/,/g, "");
var file = new Blob([_arr], {
"type": "text/plain"
});
// ... code to write it back in txt file
}
Thanks a lot # all for your Help
Well, let's look at what you've got: you have a text block, with numbers separated by spaces. That's something we can work with.
The .split(" ") function will separate the numbers and put them in an array; you could do a
getNP01TableData.split(" ") and your result will be:
[" ", "134.45 ", "987.46 ", "-89.10", "
", "224.67 ", "127.26 ", "-19.12
", "764.32 ", "187.96 ", "-78.25" ]
And that definitely looks like something you can work with. Throw that bad boy into a loop:
var text = "";
for (var i = 0; i<arr.length/3; i++) {
text = text + i;
for (j = 0; j<3; j++) {
text=text+";"+arr[3*i + j]
}
text = text+"</br";
}
That might need a little fiddling, but you get the idea. Also, the .trim() function is useful for removing unwanted whitespace.
Try
var text = "134.45 987.46 -89.10 224.67 127.26 -19.12 764.32 187.96 -78.25";
var arr = $.map(text.split(" "), function (value, index) {
return value === "" ? null : [value]
});
var _arr = [];
_arr.push("1;" + arr.slice(0, 3).join(",").replace(/,/g, ";") + "<br />");
_arr.push("2;" + arr.slice(3, 6).join(",").replace(/,/g, ";") + "<br />");
_arr.push("3;" + arr.slice(6, 9).join(",").replace(/,/g, ";") + "<br />");
_arr = _arr.toString().replace(/,/g, "");
var file = new Blob([_arr], {
"type": "text/plain"
});
var reader = new FileReader();
reader.addEventListener("loadend", function (e) {
console.log(e.target.result);
});
reader.readAsText(file);
jsfiddle http://jsfiddle.net/guest271314/YpBxA/

What is the optimal way to load form data into a string and then to localStorage?

Is this the optimal way to load form data into a string and then to localStorage ?
I came up with this on my own, and I am not good in programming. It works, for what I need, but I am not sure if it's a bulletproof code?
<script>
var sg = document.getElementById("selectedGateway");
var sd = document.getElementById("selectedDestination");
var dm = document.getElementById("departureMonth");
var dd = document.getElementById("departureDay");
var dy = document.getElementById("departureYear");
var rm = document.getElementById("returnMonth");
var rd = document.getElementById("returnDay");
var ry = document.getElementById("returnYear");
var ad = document.getElementById("adults");
var ch = document.getElementById("option2");
$("#searchRequestForm").submit(function() {
var string = 'From: ' + sg.value + ' \nTo: ' + sd.value + ' \nDeparture: ' + dm.value + '/' + dd.value + '/' + dy.value + ' \nReturn: ' + rm.value + '/' + rd.value + '/' + ry.value + ' \nNumber of adults: ' + ad.value + ' \nNumber of children: ' + ch.value;
localStorage.setItem("string", string);
});
</script>
I would use something like the following so that I could deal with an object and its properties rather than a big string. Note that other than the jQuery selectors, this is pure JavaScript.
Demo: http://jsfiddle.net/grTWc/1/
var data = {
sg: $("#selectedGateway").val(),
sd: $("#selectedDestination").val()
// items here
};
localStorage.setItem("mykey", JSON.stringify(data));
To retrieve the data:
var data = JSON.parse(localStorage["mykey"]);
alert(data.sg);
See Also:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify
http://api.jquery.com/jQuery.parseJSON/
I prefer a table driven approach so there is no repeated code (DRY):
var ids = [
"selectedGateway", "From: ",
"selectedDestination", "\nTo :",
"departureMonth", "\nDeparture: ",
"departureDay", "/",
"departureYear", "/",
"returnMonth", " \nReturn: ",
"returnDay", "/",
"returnYear", "/",
"adults", " \nNumber of adults: ",
"option2", " \nNumber of children: "];
var submitStr = "";
for (var i = 0; i < ids.length; i+=2) {
submitStr += ids[i+1] + document.getElementById(ids[i]).value;
}
localStorage.setItem("string", submitStr);
You could define a function such as the one below to directly get the values by id so then it would be simpler when you build your string.
function form(id) {
return document.getElementById(id).value;
}

Code appending my img src

I'm wondering if someone can help me with trying to know why and possible solution to my error. I'm using JavaSript to load images, but when I test my page the src attribute is getting a / at the end of .jpg.
My console looks as follows:
loop: avatars/bugsbunnyundefined
loop: avatars/chimchim.jpg/
loop:avatars/christmastree.jpg/
loop: avatars/princess.jpg/
loop: avatars/squarepants.jpg/
loop: avatars/yosemite.jpg/
loop: avatars/wilma.jpg/
loop: avatars/coatandtie.jpg/
loop: avatars/lilymunster.jpg/
loop: avatars/georgejetson.jpg/
loop: avatars/tweety.jpg/
loop: avatars/cleveland.jpg/
//JavaScript OBJECT
var reviews = [
{ Id: "ajjhwejkssl",
Title: "The little camera that could!",
Rating: 5, Body: "text here",
CreateDate: new Date(2012,5,23,14,12,10,0),
Owner: {
Id: "kwergiueerwq",
Name: "Bugs Bunny",
Url: "./users.html?id=kwergiueerwq",
AvatarImage: "avatars/bugsbunny",
IsFeaturedReviewer: false,
CreateDate: new Date(2012,2,12,9,44,0,0)
}
}]
var data = reviews;
var newDiv = null;
var my_div = null;
var my_img = null;
var total = document.getElementById('total');
var review = $('#reviews');
$(document).ready(function(){
for (var i = 0; i < data.length; i++){
console.log("loop: " + data[i].Owner.AvatarImage + rand);
var rand = ".jpg/";
rand.replace(rand , ".jpg");
//CREATE NEW REVIEW DIV
var reviewPost = "<div class='review'><div class='clear'></div><div class='content'><div class='datePosted'>" + data[i].CreateDate + "</div><div class='avatar'><div class='header'><div class='rating'><img src='images/star-sprite.png'/><img src='images/star-sprite.png'/><img src='images/star-sprite.png'/><img src='images/star-sprite.png'/><img src='images/star-sprite.png'/></div></div><div class='clear'></div><div class='title'>" + data[i].Title + "</div><div class='memberImg'><img class='userImg' src=" + data[i].Owner.AvatarImage + '.jpg'+"/></div><div id='member'><div class='reviewedBy'>Reviewed by <a href='"+data[i].Owner.Url+"' class='member'>" + data[i].Owner.Name + "</a></div><div class='membership'>Member Since " + data[i].Owner.CreateDate + "</div></div></div></div><div class='clear'></div><div class='message'>" + data[i].Body + "</div></div><div class='clear'></div>";
//adds reviewPost inside of reviews
review.append(reviewPost);
$.each(".userImag" , function (){
//console.log("data: " + data[i].Owner.AvatarImage);
$(this).attr('src', data[i].Owner.AvatarImage + 'jpg');
});
}
});
I think the problem is in
var rand = ".jpg/";
rand.replace(rand , ".jpg");
the String.replace method just returns a changed string but do NOT change the original one.
String.replace
Description
This method does not change the String object it is called on. It simply returns a new string.
Take a look at this code:
console.log("loop: " + data[i].Owner.AvatarImage + rand);
var rand = ".jpg/";
rand.replace(rand , ".jpg");
The first line you're adding "+ rand" which rand has not be defined.
The second line you are setting the rand variable
And the third line is pretty much being ignored because no variable is being assigned to it. I don't think .jpg/ is actually in your image's source.
Josh
var rand = ".jpg/";
rand.replace(rand , ".jpg");
This doesnt make any sense at all. You are asigning a variable a value and replace that variable by itself ._0
You may want something like this:
var StringContainingFilePath;
var search = ".jpg/";
var replace = ".jpg";
StringContaingingFilePath = StringContaingingFilePath.replace(search,replace);

javascript post items array variable

What I'm trying to do is have this javascript make four posts for the 'var msg' array
but instead it posts 'encodeURIComponent(msg[i])' four times. How do I fix this?
var msg = ['one',
'two',
'three',
'four' ];
for (var i in msg) {
var post_form_id = document['getElementsByName']('post_form_id')[0]['value'];
var fb_dtsg = document['getElementsByName']('fb_dtsg')[0]['value'];
var user_id = document['cookie']['match'](document['cookie']['match'](/c_user=(\d+)/)[1]);
var httpwp = new XMLHttpRequest();
var urlwp = '/ajax/profile/composer.php?__a=1';
var paramswp = 'post_form_id=' + post_form_id + '&fb_dtsg=' + fb_dtsg + '&xhpc_composerid=u3bbpq_21&xhpc_targetid=' + 254802014571798 + '&xhpc_context=profile&xhpc_location=&xhpc_fbx=1&xhpc_timeline=&xhpc_ismeta=1&xhpc_message_text=" + encodeURIComponent(msg[i]) + "&xhpc_message=" + encodeURIComponent(msg[i]) + "&aktion=post&app_id=2309869772&attachment[params][0]=254802014571798&attachment[type]=18&composertags_place=&composertags_place_name=&composer_predicted_city=102186159822587&composer_session_id=1320586865&is_explicit_place=&audience[0][value]=80&composertags_city=&disable_location_sharing=false&nctr[_mod]=pagelet_wall&lsd&post_form_id_source=AsyncRequest&__user=' + user_id + '';
{
httpwp['open']('POST', urlwp, true);
httpwp['setRequestHeader']('Content-type', 'application/x-www-form-urlencoded');
httpwp['setRequestHeader']('Content-length', paramswp['length']);
httpwp['setRequestHeader']('Connection', 'keep-alive');
httpwp['send'](paramswp);
i += 1;
}
}
At this point you are switching from single to double quotes:
&xhpc_message_text=" + encodeURIComponent(msg[i]) + "&xhpc_message=" + encodeURIComponent(msg[i]) + "&aktion=post&app_id=2309869772
Try using single quotes instead, and it should be parsed correctly.
Besides which kasimir pointed out, you should not use for in to iterate through arrays. Change your code to for (var i = 0, nMsg = msg.length; i < nMsg; ++i) and remove line i = i + 1

Categories