Array length issue in azure mobile services - javascript

I'm sending an array to the service
[
{
"toppingid": "ABB934CB-EAB7-4863-B832-7F533DA08E2F",
"toppingname": "Default",
"toppingprice": "0.000000"
}
]
When I console.log it shows as above. I do console.log as below
toppinglistforCart = [];
toppinglistforCart = request.body.toppinglist
console.log(toppinglistforCart);
But when I try to toppinglistforCart.length it returns 132 for some peculier reason.
and if I do console.log(toppinglistforCart[0]) then it returns [ very strange. Did someone else came through this same issue?
Thanks for your time

Your toppinglistforCart variable appears to be a string, with length 132. (It doesn't work in older IE, but) JS lets you use the topplinglistforCart[0] syntax to access individual characters within the string, similar to how the same syntax on an array accesses individual array items.
You need to parse the JSON content of your string to create an object:
toppinglistforCart = JSON.parse(request.body.toppinglist);
Note also that your first line:
toppinglistforCart = [];
...is not needed at all - it sets toppinglistforCart to a new empty array but then the next line sets toppinglistforCart to something else so that empty array gets thrown away.

Related

Javascript pushing Array to Array but concatenating instead

I'm trying to push an array (multiple times) into another array. Instead of an array of arrays, I'm getting all the values from the multiple push attempts as a single array. I've tried pushing an array implicitly (i.e. push([val1,val2]), explicitly creating a new Array, then pushing the new Array. Here's the key part of the code:
var coordinates=[];
...
for(i=0;i<6;i++)
{
...
for(var j=start;j<circum[i].length;j++)
{
var segmentCoords=[];
...
if(segmentFlag===false)
{
segmentCoords.push([i+1,segmentLength]);
segmentFlag=true;
}
...
if(segmentFlag===true)
{
var tempArray=new Array(i+1,segmentLength);
segmentCoords.push(tempArray);
segmentLength+=sectorLength;
coordinates.push(segmentCoords);
segmentFlag===false;
}
...
}
From the many stackoverflow questions/answers I've looked at, I expect my coordinates array to look something like this: [[val1, val2],[val3,val4],[val5,val6]]. Instead it's [val1,val2,val3,val4,val5,val6]. That is what I would expect if I were using .concat() or .apply().
Can anyone explain why my code isn't generating an array of arrays?
I've got the full code here https://jsfiddle.net/Seytom/7xm9s4qr/ in case you want to see more of it.
You seem to be fooled by your console.log. Notice the difference between these two statements:
console.log( 'string ' + [[1,2],[3,4]] ); // string, '1,2,3,4'
console.log( 'string ', [[1,2],[3,4]] ); // string, [[1,2],[3,4]]
Because you are coercing the array into a string, this is the result. Its the same as:
console.log( new Array([1,2],[3,4]).join(',') ); // 1,2,3,4
It's simply what arrays do when you join them, regardless of whether they are nested. It is better to log the array separately so you can explore it in your console, so simple print your string and then add the array as the second argument. (The console takes an infinite amount of arguments and will print them all as one statement - safari even prints the first as a special type if its a string so its clearer to read).
In short: push behaves exactly as expected, and your code should simply work as intended, but the printing to the console seems to leave a bit to be desired :).
Use Array.concat:
var arrA = [0];
var arrB = [1, 2];
while (arrA.length < 10) {
arrA = arrA.concat(arrB)
}
console.log(arrA)

Node.JS behaves strange

I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.

Why are my defined strings printing to the console as undefined?

I've written a very simple application that pulls all the tracks off of a spotify playlist. First, it gets the track JSON objects using an AJAX request and puts them in an array called tracks[].
Next, I iterate through this array, and in each iteration I pull out the strings for the name of the song and the artist for each track. I put these in a concentrated string. This string is then stored in a new array called complete. This is done for each track.
Essentially, complete is an array that looks something like
[
"Sympathy for The Devil, The Rolling Stones",
"Come Together, The Beatles",
...
]
At this point I have a strange issue. According to chrome's debugger, the array complete has all of the correct values inside of it. However, when I attempt to console.log any element of complete I end up with the value 'undefined'. Stranger yet, if I console.log the expression I use to get the two strings and stitch them it prints the correct value.
Why does this happen and how can I fix it so it can console.log the correct values
Here is the code that iterates through stored JSON objects, stores them in new array, and prints:
function print() {
for(var x = 0; x < 4; x++) {
for(var n = 0; n < 100; n++) {
try {
//this logs correct
console.log(tracks[x].items[n].track.name + " " + tracks[x].items[n].track.artists[0].name);
//these have correct value
var deb = (tracks[x].items[n].track.name + " " + tracks[x].items[n].track.artists[0].name);
complete[z] = deb;
z++;
console.log(deb); //throws no error, prints fine
console.log(complete[z]); //prints undefined
} catch(err) {
//no exception ever thrown
}
}
}
}
I don't do too much JS, sorry if I'm missing something obvious.
Right after assigning complete[z], you are incrementing z. When printing, you are not accessing complete[z] anymore, but complete[z+1] which is not yet defined. Try moving the incrementation after the console.log command.
Well, in your example above, you've incremented z (which I assume was defined earlier somewhere?) after setting the value on your array. So when setting the value on the array, you've set it to complete[5] (or whatever) but you're logging complete[6] which is most likely outside the range of your array.

Javascript: Calling a function in an object literal

I'm learning to program in Javascript and I'd like some help/clarification.
I declared an array that contains animal names. I defined a function that I use to split a string in two. Then I create an empty object literal and add an animal and corresponding breed. I'm trying to invoke the separateWords function in the object literal, but I need some clarification. Here's my code:
var myPets = ["Bengal Bobcat", "Beagle"];
var separateWords = function (string) {
return string.split(" ");
};
var nameCollection = {};
nameCollection.cat = separateWords(myPets[0]);
nameCollection.dog = myPets[1];
nameCollection.fish = null;
When I enter console.log(nameCollection) I get the following:
Object {cat: Array[2], dog: “Beagle”, fish: null}
cat: Array[2]
0: "Bengal"
1: "Bobcat"
length: 2
However, when I enter console.log( separateWords(myPets[0])), I see:
[“Bengal”, “Bobcat”]
I don’t understand why the value of cat shows up as Array[2].
The console displays it as Array[2] as it would be (potentially) unreadable if it expanded it fully. One way to see everything is to stringify it using JSON.stringify which goes through each item in the object recursively and calls toString() on it:
var myPets = ["Bengal Bobcat", "Beagle"];
var separateWords = function (string) {
return string.split(" ");
};
var nameCollection = {};
nameCollection.cat = separateWords(myPets[0]);
nameCollection.dog = myPets[1];
nameCollection.fish = null;
document.body.textContent = JSON.stringify(nameCollection);
You are assigning to cat the result of the separateWords() function call, passing myPets[0] as a parameter.
separateWords() returns an array and with the myPets[0] input it returns a new array with the "Bengal" and "Bobcat" values splitted by the whitespace.
The split() function is the one creating an array with the splitted values and this result is returned by your separateWords() function, which also is the value assigned to the cat object member.
Each browser implements its console like it wants.
So your browser decided to implement the behavior you describe.
If you don't like it, propose a better idea to the developers of this browser. Or use another browser.
I am going to assume you are using Chrome Developer Tools or Firebug.
Developer tools condenses arrays and objects into easily readable lines you then inspect further with. What I mean is, you push the little arrow next each line in the console log to further inspect each object. I will use pictures to explain this.
Here I am assigning an array and then assigning an element in an object to that array as so:
As you can see when I log the object it show's an Array[2] rather than expand the array. In this next picture I then expand the array to inspect it.
Why is this exactly? My first thought is ease of readability. If you have an app that is complex and you have numerous debugging console logs, you can see all the logs on single lines making it easier to hunt down specific logs. As well, if you have a very large and complex object, it is arguably easier to read all the root elements on each line without expanding all the objects and arrays found within that object recursively.
String.prototype.split() returns an array containing the two values in the string which have been split. Read through this.
nameCollection.cat = separateWords(myPets[0])[0]; // nameCollection.cat == Bengal
nameCollection.cat = separateWords(myPets[0])[1]; // nameCollection.cat == Bobcat
This is simply how javascript (and many other languages) work. When you try to print "nameCollection" javascript doesn't automatically do a nice job of printing the cat array. Instead, it simply prints some type related information, which in this case is saying "cat" is an array of length 2.

Array containing objects has wrong length

I have an array like:
errors = [ {...}, {...}, {...} ]
It's an instanceof array, yet it only returns 1 for .length?
Relevant code:
if(data.error){
errors.push({'element':ele,error:data.error});
}
//Above is looped a few times and there are N number of errors now inside
console.log(errors) //Returns 2+ objects like {...}, {...}
console.log(errors.length) //Returns 1
For Uzi and Muirbot, here's the errors array:
[
Object
element: b.fn.b.init[1]
error: "You must enter "example" into the field to pass"
__proto__: Object
,
Object
element: b.fn.b.init[1]
error: "Crap!"
__proto__: Object
It is correct, this code:
var errors = new Array();
errors.push({'element':'ele', error:'data.error'});
...adds ONE object to the array. The object has two properties.
It's possible your code is executing in an order other than what you're expecting. ie, when you log both errors and errors.length, errors does contain only 1 object. But after that you are adding to the errors array, and only after that are you looking at the console. At that point you could see a larger array in errors for two reasons - first, your actual code isn't logging errors but some object that contains errors. In that case the console display is live, and will show you not what was in errors at the time, but what is in it now. Alternatively, the console could just be taking some time to log errors.
Without more code I can't be sure if this is the case. But you could verify it by replacing console.log(errors); with console.log(errors[1]);. If errors is really only 1 long at the time, it will log undefined.
The problem was that Chrome's Web Inspector's console.log is an async event. So, the length was a property lookup so it gave that back instantly, but the object with two items inside was held off until the rest of the events had fired.
In the future I, and others with this issue, should use debugger; instead.
is it an Array object or something that resembles it?
arrays do work:
> a = [{a:1}, {b:2}]
[Object, Object]
> a.length
2
you'll have to provide more code.
and now that you've provided the relevant code, the correct answer is what Steve Wellens said (which was downvoted, by the way).
Array.push adds a single element, objects may have more than one key but they're still a single object so your real case was different from your original example, which of course works.
another possibility:
> a = []
[]
> a.length = 2
2
> a
[]
> a.length
2
> a instanceof Array
true

Categories

Resources