Different console.log(variable) outcomes for exactly the same variable - javascript

My issue is that logging exactly the same variable value, but accessing it in a different way, yields two different results.
console.log(car[1].wheels.radius)
logs the integer 20 to the console, since 20 is the value assigned to car[1].wheels.radius.
Now, if I log the whole object:
console.log(car[1])
and access the element radius manually in the console, I can see that its value is 'NaN'.
Same happens when I use car[1].wheels.radius in a calculation, for instance 3.14*car[1].wheels.radius returns NaN, even though this is a multiplication of 3.14, a number, and car[1].wheels.radius, also a number, so it should return a number.
Anyone knows what the issue might be?

OK to actually answer the question in the title about why you get different results when logging a variable -
If a primitive is sent to the log then it is immediately displayed with the value so in this case when you send car[1].wheels.radius it does have the value 20.
However when you log an object,car[1], the values for the attributes are not actually shown until you inspect the object in the console (if you are using chrome there is a little blue (i) which explains this). Think of it like you are logging the reference, the actually objects state will not be shown until you expand/inspect that reference.
So you are performing some calculation on car[1].wheels.radius which changes it from 20 to NaN at some point which explains the difference.
The cause of that problem is unknown from the amount of code you have shown. Use the debugger to step through your code and look to see when this value changes.

Related

No array operations work on getLangs() from ngx-translate/core TranslateService

I work on an Angular (v13) project which uses ngx-translate/core for i18n. There are multiple languages (15 currently) configured. I find the following very strange behaviour (TranslateService is injected as this.translateService):
Calling this.translateService.getLangs() returns an array with the 15 language codes as expected. I can log this value or e.g. configure a dropdown select with these values.
However, I can do absolutely no array operations on this value, including indexing [0] (says undefined), .length (returns 0), or for-in or for-of. No ... operator to create a new array or object with the values, no Object.assign([], langs), no Array.from() - they just return empty arrays. Let alone .map(), .forEach(), etc.
typeof says object, Array.isArray() says true.
Some basic example code:
ngOnInit(): void {
console.log(
this.translateService.getLangs(),
this.translateService.getLangs().length,
this.translateService.getLangs()[0],
this.translateService.getLangs().includes('en'),
this.translateService.getLangs().includes('aa')
);
}
shows in the console:
[] 0 undefined false false
and if I expand the [] it shows the 15 codes (including 'en'), and length: 15.
Questions
Am I reading the ngx-translate documentation wrong (that what is there)?
Am I using it wrong somehow due to not understanding something?
Is this a bug in ngx-translate?
Is this a bug in JavaScript?
Is there any workaround?
Thank you to Amer for his comment pointing me in the right direction.
The problem occurs because this.translateService.getLangs() is called before languages have been loaded via this.translateService.addLangs(). The language values are obtained via a HttpClient.get() request, which returns an Observable and calls addLangs() once the results are received (refer Observable.subscribe(...)). (So no funny happenings, just a wrong understanding.)
The simple solution is to only do any operations on the array of languages in the complete callback of the Observable returned by HttpClient.get() (or use one of the other synchronization mechanisms available). This was a bug in the original code and has now been fixed.
The browser (Chrome) logging [] (which could then be expanded to the full array) was a confusion on my part. When the array is available at logging time, it is logged as expanded, e.g. [ "ar", "en", .... ]. (By the time I clicked on the expansion widget in the console, the array had obviously been loaded in the mean time, which enables it to be shown on expansion.)
I strongly advise against synchronization via timeouts as someone may wrongly read from Amer's comment, where it is suggested only for problem detection. One should always use one of the synchronization methods (Promises, Observables, events, etc. etc.) in final code to synchronize between asynchronous processes.

TypeScript: empty array is initialized with values, and those values cannot be changed

Now, this might just be me not knowing some basics of how TypeScript works, as I am pretty inexperienced with it, but all my attempts to find a solution to this issue have so far failed.
In one of my functions I am trying to get an item-by-item disjunction of two boolean arrays. However, when I am initializing an empty array to then fill with new values, something strange happens.
let res = new Array<boolean>();
console.log(res)
Output of the freshly initialized array "res"
As you can see, while array is depicted as empty in its collapsed form, opening it for more info reveals that it actually already has 5 "false" values in it. (note: it is not always 5 falses, this is just an example)
When the function then starts pushing new values into it, while those values are depicted correctly in the array's preview, in reality there are still the same five "false" values inside it, and those are not being changed in any way. Furthermore, logging specific items from this array returns correct values
res.push(a[i] || b[i])
console.log("disjunction at position " + i.toString())
console.log(a[i])
console.log(b[i])
console.log(res[i])
console.log(res)
Console output
This function then returns a new boolean array to be pushed into an array of arrays. When I am logging this array of arrays, it depicts not arrays of values the function filled them with, but instead those weird values that have been put there with initialization. This does not seem to affect the first array (and only that one).
Array of arrays
As I said, I might just miss some crucial information about how arrays in TS/JS work. Right now I am a bit lost, so any help would be appreciated!
Turns out it was just me not knowing how dev console works. The big array of arrays is being filtered after being filled up, and because console shows all the arrays in real time, filter causes it to retrospectively depict them as full of falses. Temporarily removing filter proved this hypothesis.

How to get count object in javascript? [duplicate]

I have an array filled with objects. It contains 23 items in total, however when I perform a .length on it, it returns 20.
// Get the new routes
var array = PostStore.getPostList();
console.log(array.objects);
console.log(array.objects.length);
Image of what my console returns:
What's going wrong here?
The problem is probably that the array changed between the time you logged it and the time you opened it in the console.
To get the array at the logging time, clone it:
console.log(array.objects.slice());
console.log(array.objects.length);
Note that this won't protect against the array element properties changing. If you want to freeze them too, you need a deep cloning, which is most often possible with
console.log(JSON.parse(JSON.stringify(array.objects.slice()));
This won't work if the objects aren't stringifyable, though (cyclic objects, very deep objects, properties throwing exceptions at reading, etc.). In that case you'll need a specific cloning, like my own JSON.prune.log.
A alternative to logging is also, in such a case, to debug. Set a breakpoint and look at the objects while the code is stopped.

Javascript map string lookup. Can't find key even though key is in object

I must be missing something pretty standard here.
I have a map mapping string to object. What I write out:
console.log(playerMap, this.id(), playerMap[this.id()]);
What it prints out:
this does not make a lot of sense to me since the key seems to be right there.
Fiddle
Based on your Fiddle, apparently your playerMap is not yet initialised when you new FeedViewModel(), if you change your console.log to
console.log(Object.keys(playerMap).length, this.id(), playerMap[this.id()]);
you will see the object is empty
> 0 "123243df6" undefined
It's always confused when you console.log object because the object displayed is only resolved when you expand the > in the console. It is not the state of the object when you console.log'd the object.

jquery console.log and alert different value

I realy cant understand javascript. Maybe someone can explain me the difference:
validationErrors[value.element.name] = value.method;
console.log(validationErrors);
alert(validationErrors);
console.log(validationErrors) returns well formed array with values, and alert(validationErrors) returns empty array. Why?
The console is more of a debugging environment and can understand the JS objects that are passed in the log function.
Alert on the other hand is a dialog box and will coerce its arguments into string values. Which is why the output is not as well formatted as the console.
Here is a little snippet of what is actually happening in the alert box.
var validationErrors = [ 2, 3, 4 ];
console.log(toString(validationErrors));
Output >> "[object Window]"
It's also best practice to use the console for logging purposes and not the alert box.
you can try this
alert(JSON.stringify(validationErrors));
Alert have some limit according to browser it varies but most You'd probably be best staying under 1000 characters though, as many browsers seem to begin to truncate after 999.
And if you are giving object in alert it will never reflect the values so prefer console for object and other data type can be used in alert but its not a good practice.
console give proper view of data like object in array can be studied easily in console.
Alert is used to print messages, which means it is used to display string values. When you pass anything other than string to alert, it calls .toString function of it and prints the output.
Now why did you get a blank string?
An array is supposed to have indexed values only. So you can do array[index] = "bla bla". But when you do array["something"] = "something else", it adds a property to that array (since arrays are also objects in Javascript).
According to MDN
The toString() method returns a string representing the specified array and its elements.
In simple, it will loop over length of array and join all elements with ,(comma)
But you do not have elements in it. You have set properties. So length is 0 and hence it returns ""
Following is a simulation
var a = [];
a["test"] = "foo";
console.log(a);
console.log(a.toString());
alert({})
Reference
Alert
Array.prototype.toString
All objects in Javascript are passed by reference. So when you passed something to console.log() and it would be changed in code further, in console you will see changed value. On other hand, alert() displays message box and stops code execution, so in message box you see values exactly as they are at alert()'s call time.
For debugging purposes, you may want to use browser's debugger - I recommend Chrome Dev tools. There is free course from codeschool.com to help you discover such great tool: https://www.codeschool.com/courses/discover-devtools

Categories

Resources