Object array gets overwritten by the last object - javascript

I have this array of objects being loaded:
$(document).ready(function () {
$("<div></div>").load("/Stats/Contents #stats", function () {
statcount = $(".list-group-item", this).length;
for (var j = 0; j < statcount; j++) {
statList.push(stat);
}
for (var i = 0; i < statcount; i++) {
statList[i].statId = document.getElementById("statId-" + (i + 1) + "").value;
statList[i].productDescription = document.getElementById("productType-" + (i + 1) + "").value;
statList[i].lastMeasuredInventoryAmount = document.getElementById("statLastMeasureAmount-" + (i + 1) + "").value;
}
)}
)}
.... and so on
Then I get the changed values and save them, however, in the ajax post call, all of the array objects are same (the last one assigned), looks like they get overwritten.
Any ideas? I saw these deferred/promise type code but not sure if there's simpler way.
Thanks.

It sounds like you take the statList array and then push that up to the server, with any respective change. Rather than building and maintaining a list like this, have you thought of switching it around and just grabbing the results out of the markup and building up the array at save point?
$("btnSave").on("click", function(e) {
var data = [];
$(".list-group-item").each(function() {
data.push({
statId: $(this).find(".statid").val(),
.
.
})
});
You wouldn't need to give every element an ID (but could) as my sample uses CSS classes to find the element within the current list item. Additionally, if these are inputs, you could serialize them from the root element more efficiently...

Related

JavaScript create appropriate number of rows and columns based off of list length

I've been struggling with converting the following C# code into something I can use in JavaScript:
var g = Model.List.GroupBy(r => Model.List.IndexOf(r) / 3).ToList();
It's use was to create the appropriate number of rows, with the appropriate number of columns within them. So for example if the list had 6 elements it would allow me to create 3 rows with 2 columns in it, this was all done in razor pages using the above GroupBy and the below code:
foreach (var parent in g)
{
#Html.Raw("<div class='row'>");
foreach (var item in parent)
{
// populate contents of row
}
#Html.Raw("</div>");
}
However for certain reasons I can't do this in Razor and need to create an alternative in JavaScript but I'm struggling to figure out a way to do this.
Primarily because I don't understand entirely how 'GroupBy' creates the list of groups and what would be a suitable alternative.
Any help, or pointing in the right direction would be great. I've tried a few solutions I found online for creating 'GroupBys' but I couldn't get them to work the way I was expecting. I also thought maybe I could split the original list into a list of dictionaries, but again had little success. I'm possibly missing something obvious.
In the end it turns out I was just missing the obvious answer, I found this excellent SO answer. I had looked at slice but couldn't quite visualise how to use it for my problem (obviously been a long day).
The post showed this snippet:
var i,j,temparray,chunk = 10;
for (i=0,j=array.length; i<j; i+=chunk) {
temparray = array.slice(i,i+chunk);
// do whatever
}
In the end my JavaScript code looked something like this:
var listdata = await octokit.repos.listForUser({ "username": "", "type": "owner" });
var chunk = 2;
var loop = 0;
var tempArray = [];
for (var s = 0; s < listdata.data.length; s += chunk) {
tempArray[loop] = listdata.data.slice(s, s + chunk);
loop++;
}
var htmlString = "";
for (var t = 0; t < tempArray.length; t++) {
htmlString += "<div class='row'>";
var innerArray = tempArray[t];
for (var r = 0; r < innerArray.length; r++) {
var repo = innerArray[r];
htmlString +=
"<div class=\"col-md-6 col-sm-6 col-xs-12\">" +
"<div>" + repocontent + "</div>" +
"</div>"
}
htmlString += "</div>";
}
So with a list that's 6 items long, it gets split into an array that contains 3 lists of 2 items. Then I just create the html string using two for loops to create the outer bootstrap rows and the inner column classes. There's probably a more efficient way to do this but this worked a treat.

Javascript for loop with array

Trying to fetch and display data from an array in a for loop but it's only showing one entry. I'm executing this in a trigger for Storyline and when viewing Storyline in the browser I don't get any help from the inspector.
function showInfo(data) {
for (var i = 0; i < data.length; i++) {
var player = GetPlayer();
player.SetVar("name", data[0].name + "\n");
}
}
Seems like something simple to do but not sure whats going on. Perhaps Articulate Storyline adds an extra layer of issues not forseen.
but it's only showing one entry
this is because you're accessing at 0 index for each. You need to use i to correctly iterate over every element.
see:
function showInfo(data) {
for (var i = 0; i < data.length; i++) {
var player = GetPlayer();
player.SetVar("name", data[i].name + "\n");
}
}

Sorting elements in array

I have an array containing a list of images that I have stored online:
var imgs = ["img1","img2","img3"...];
They are displayed as such:
var child, i;
for (i = 0; i < imgs.length; i++) {
child.style.backgroundImage = 'url(https://mywebsite/images/' + imgs[i] + '.jpg)';
$('body').append(child);
}
However, I'm looking to try to display the images based on their attribute, that can change depending on a user action.
This attribute will look like this:
child.setAttribute("class", 0);
Say for example, the user decides to click on an image, then the attribute of the image he clicked on will increment. So the class will no longer be '0' but '1'. And because of so, the image will be placed before the others in the array.
Assuming 'img2' was clicked, then the array would look like:
imgs = ["img2","img1","img3"...];
I feel like the method I'm going by is inefficient and I have considered using objects or even 2d arrays, but I'm not sure where to start and lack experience. However, if this isn't "such a bad way" to get started, then I'd appreciate if someone showed me how I could move the elements in the array.
Thanks in advance.
You can try this:
$('body').find("img").on("click", function()
{
$(this).data("count", (Number($(this).data("count")) + 1));
reOrderImages();
});
function reOrderImages()
{
var imgs = $('body').find("img");
for (var i = 0; i < imgs.length; i++)
{
var img1 = $(imgs[i]);
var img2 = (imgs.length > (i + 1) ? $(imgs[(i + 1)]) : false);
if (img2 && Number(img1.data("count")) < Number(img2.data("count")))
{
img1.before(img2);
}
}
};
Fiddle. Here I'm using data attributes instead of the class attribute, which isn't designed for your case. It just swaps the elements with before() method.
You can use array.sort with a compare function. getClass method here is some method which returns current class attribute of an image by it's url
imgs.sort(function(img1, img2){
var class1 = getClass(img1);
var class2 = getClass(img2);
return class1 - class2;
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Storing and retrieving objects in javascript array();

Hi I've searched for the answer but since the tutorials online are all friends = ("bob","fred","joe"); I dont get anywhere. I would like to be able to store several objects with 1-3 values in each index of the array like:
map = [{ground:0},{ground:0, wall:1},{ground:0, item:3}]
The object I have right now looks like:
node = {};
node = {ground:0, object:1};
But when I try the array way I can't access it, all I get "object Object". What would be the correct way to get the values from the map array one by one?
Do you mean:
var map = [{ground:0},{ground:0, wall:1},{ground:0, item:3}];
for(var i = 0; i < map.length; i++) {
console.log(map[i].ground + " item " + map[i].item);
}
Not sure what you want, or what you mean by "the array way", but if you want to get all the values for say ground, then:
var map = [{ground:0},{ground:0, wall:1},{ground:0, item:3}]
for (var i=0, iLen=map.length; i<iLen; i++) {
alert(map[i].ground);
}
Edit
...
alert('item ' + i + ' : ' + map[i].ground); // item 0 : 0
...

How to write an index loop for a json object

I have an image updater. I am loading by JSON the exact same file/partial that show my images.
I would like to write a loop that runs through an index and replaces every image with its equal.
This is the first div in my json object :
[{
"photo": {
"position":1,
"photo_file_size":45465,
"created_at":"2010-10-05T09:51:13-04:00",
"updated_at":"2010-10-05T09:52:29-04:00",
"photo_file_name":"tumblr_l0x861Yc5M1qbxc42o1_400.jpg",
"is_cropped":true,
"crop_h":null,
"photo_content_type":"image/jpeg",
"id":216,
"caption":null,
"crop_w":null,
"photo_uploaded_at":null,
"crop_x":null,
"processing":false,
"gallery_id":26,
"crop_y":null
}
},
...
The next div in that json object would be something like gallery_photos_attributes_1_id .
Update
This is what I got so far.. but the load() method doesn't work correctly. I get a "ONLY GET REQUESTS ALLOWED"
$.getJSON(url, function(data) {
for (var i = 0; i < data.length; i ++) {
url2 = "/organizations/" + 1 + "/media/galleries/" + 26 + "/edit_photo_captions"
var image = $("#gallery_photos_attributes_" + i + "_caption");
url_str = image.siblings("img").attr("src").substr(0, str.lastIndexOf("/"));
image.siblings("img").load(url2, image.siblings("img"));
};
})
Although I'm not 100% I got you right, try this piece of code.
var url = "/organizations/" + organization + "/media/galleries/" + gallery + "/update_photo_index"
$.getJSON(url, function(data) {
// the outer is an array, so just loop as usual
for (var i = 0; i < data.length; i++) {
// fetch something for the current photo
var caption = $("#gallery_photos_attributes_"+ data[i].photo.id +"_caption");
// update source
caption.siblings("img").attr("src","/path/to/images/"+data[i].photo.photo_file_name+"?c="+parseInt(Math.random()*10000));
// update caption
caption.html(data[i].photo.caption);
// and so on...
}
});
Remember that in JSON "[ ... ]" describes an array whereas "{ ... }" describes an object. With an array you can just loop as with every other javascript array. If you got an object, it's like any other javascript object whose fields are accessible either with object.field or object['field']. So using JSON in javascript is nearly a no-brainer.
Hope that helps.

Categories