Printing object gives different value than printing a property of that object - javascript

I've got a strange situation in my typescript file where these two console.info calls show separate values for overage:
this.rows[index].overage = 17;
console.info(this.rows[index].overage);
console.info(this.rows[index]);
The first printout shows the expected value of 17. The second, where the whole object is displayed, show the old value of 90 for overage. How is that possible?
Rows is defined like so:
rows: UsageDisplayData[];
export interface UsageDisplayData {
id: number;
overage: number;
// A bunch of other properties
}

It's hard to say without an MVCE exactly what is happening, but the expanded view in the dev console is usually a "live" view and thus will show whatever the latest value is. Example:
let obj = { m: 17 };
console.info(obj.m);
console.info(obj);
obj.m = 90;

Related

How do I correctly clone this Map?

In my React app, at one point I'm trying to copy a Map from an object, but it's not working for me.
The initial user object has the structure:
user: {
videoTracks: Map,
... other fields...
}
If I do a console log on user, I get this for videoTracks:
Then I do this: const newVideoTracks = user.videoTracks;
and I would expect newVideoTracks to be the same as the first image, but instead I get the following:
It has 2 entries and size:2, but it says Map(1) at the top.
I know the console isn't always accurate, but in this case when I subsequently use newVideoTracks, it behaves as though there is only 1 entry.
I assume I need to do some cloning rather than just copying it, so I tried both of the following:
const newVideoTracks = new Map(user.videoTracks); - this didn't make any difference
const newVideoTracks = Object.assign({}, user.videoTracks) - caused a crash
What's the correct way to do this?

JavaScript problem converting strings inside object (inside loop)

While building a carousel module for Joomla I am having 2 JavaScript issues I can't get fixed. I've been trying for 2 days. Hopefully someone here can point out what I am doing wrong.
I can't get a boolean from a string "0" or string "1"
And I can't JSON.parse() to convert an object string to a JavaScript object
The situation:
To be able to have multiple instances on 1 page I am passing each modules individual settings (via php) to 1 object in my javascript file. Each module is 1 key value pair inside the object, the value being its own settings object. Basicly, this is how the JS recieves it:
const moduleSettings = {
"103":{"items":3,"margin":5,"loop":"1","center":"0","responsive":"{0:{items:1}}"},
"105":{"items":3,"margin":5,"loop":"0","center":"1","responsive":"{0:{items:2}}"}
};
Next I need to loop over each module to initialize the settings. This is done on ready using jQuery.
jQuery(document).ready(function() {
// Loop over each module
const modules = Object.keys(moduleSettings);
for (const id of modules) {
const target = "carousel-" + id;
const params = moduleSettings[id];
// Callback to evaluate true/false params
function eval(singleParam) {
return params[singleParam] === "1";
};
// Initialize carousel
jQuery(target).owlCarousel({
items: params.items,
margin: params.margin,
loop: eval("loop"),
center: eval("center"),
responsive: JSON.parse(params.responsive)
});
};
});
The carousel properties items & margin are numbers. No problem there, but these are recieved as numbers from the start.
The problem:
The properties loop & center should return a boolean, based on the callback function eval(). But they just return the string "0" or "1".
The property responsive should return an object. But this still remains a string object "{...}".
The console error:
The first problem above does not block functionallity. It works, but I want to understand why my values are not booleans.
The second problem however causes console error and make the carousel not work. This is only IF responsive is not an empty string. When responsive is an empty string, it works. But I need the responsive setting.
I've been looking for the cause of this issue for 2 days now. It's getting frustrating. Any pointers would be most helpfull. Thanks!
instead of using eval function use can you below
jQuery(target).owlCarousel({
items: params.items,
margin: params.margin,
loop: !!params.loop,
center: !!params.center,
responsive: JSON.parse(params.responsive)
});
For the second issue, you need to change the structure from your server side code to generate this module settings JSON. The responsive object is not a proper JSON. its should be like
responsive: {items:1} or responsive: [{items:1}]
If you can post that code then I can tell you the change need to made there.
In the example you've provided, you're not evaluating the params field by name provided as a singleParam argument, but the actual params.singleParam field, which is undefined. To fetch field by it's name use brackets syntax: params[singleParam].

Javascript: JSON key values not updating on request

I'd like to update my JSON value based on selection.
So for that I have simply update my json value as data.childShow = true.
Now as per the screenshot on line no 78 it's actual value is false and after updating it's value to true ( ref line no 84 ) and it shows as value updated on line no 85 but when i expand that console object it shows as false.
So, why the values are differing when open the object on console log ?
Screenshot while not opening object of line no 85
P.S: Before raising this question I have already tried this demo, but it is not working in my actual application so that i raised this question.
Try this thing in console it might solve your confusion. Add an object like let data = { childShow: false }. Then log it in console. Do not expand right now. Now change the value of data.x = true; in expanded value but it also has childShow=false in first line. Now expand console log value. You can see it is displaying childShow = true. So it might be fetching current values when we expand.
You can also log childShow and check what exactly values hold by data.childShow. Like in below snippet. It will show you when you do console.log(data.childShow); first time it will show false and second time it will show true which is as expected.
Try with below like. 1. Open console of browser. 2. Click on Run Code Snippet. 3. Expand object in console.
const data = {
childShow: false,
}
console.log(data);
console.log(data.childShow); // Output false
data.childShow = true;
console.log(data);
console.log(data.childShow); // Output true

meteor minimongo getting inconsistent collection.findOne() results

I've been trying to debug a chunk of code for some hours now, banging my head against the wall, and finally pinpointed my issues to a place in the code where assigning the results of a collection.findOne() call to a variable is giving me different data than what I see with a console.log() of the same findOne() on the previous line.
prePostState = function(thisStID) {
console.log(Students.findOne({_id:thisStID}));
var stTemp = Students.findOne({_id:thisStID});
console.log(stTmp);
var testsTemp = stTmp.tests;
The collection object has a 'tests' array. In this instance, the array contains 3 objects as its elements.
While both the console.log() lines return something like this
Object {_id: "eXf9dqQbaemKS24Ti", name: "Student,Name", group: "none", site: "SiteName", tests: Array[3]}
Expanding each shows different data. The first one shows the correct tests: Array[3], the second one shows tests: Array[1], and the single element in that array also has data that is different from the matching element in the full array.
----Update----
Doing some further testing, I've changed the code a bit.
prePostState = function(thisStID) {
console.log(Students.find({_id:thisStID}).fetch()); //1
var stTmp = Students.find({_id:thisStID}).fetch();
console.log(stTmp); //2
console.log(stTmp[0].tests.length); //3
for(var i = 0; i < stTmp[0].tests.length; i++) {
console.log(stTmp[0].tests[i]); //4
}
1 Returns:
[Object]
0: Object
_id: "AqLHB8hT8GxzQ7zyD"
group: "none"
name: "Student,Name"
site: "SiteName"
tests: Array[3]
2 Returns:
[Object]
0: Object
_id: "AqLHB8hT8GxzQ7zyD"
group: "none"
name: "Student,Name"
site: "SiteName"
tests: Array[1]
3 Returns:
3
The for loop at 4 repeats three times and prints out each of the three objects in the tests array.
Obviously this means I can access the data I need. Instead of
var testArray = stTmp.tests;
Which leaves me with an array with only a single element, I will just have to get the length of stTmp.tests, and then use a for loop to access each element by index and insert them into the testArray variable.
So I can continue on, but I still don't understand the behavior I'm seeing. I'm on a bit of a timeline to keep making progress at this point, but when I have some time I may revisit this and try and replicate it in a meteorpad or other form that I can share the full code with.
1) If you modify a return value from Minimongo, don't expect it to persist. Minimongo was specifically written this way, so you are forced to use update operators to update the values.
2) The correct projection API is Coll.find({..selector..}, {fields:{..projection..}})

Changing the variables of a class in OOP in javascript

I have defined a function called Node which stores the properties of nodes in a graph data structure. The function is something like this:
function Node(){
...
this.outEdges = [];
this.inEdges = [];
...
}
where the inEdges and outEdges store elements of type Edge which is another function I have defined. During the program these arrays are filled with elements.
At some point in my code I need to reset these two arrays so I write:
nodes[i].outEdges.length = 0;
nodes[i].inEdges.length = 0;
where nodes is an array of elements of type Node and I am accessing an element in a for loop.
The problem is, after setting outEdges and inEdges to 0, I expected them to be [] in the nodes[i] property list. However, when I output nodes[i] into console, the outEdges and inEdges still have the elements in them. The stranger thing is that when I output nodes[i].outEdges to console, it prints [] , which is correct, but clicking on [ ] again opens the list of the elements! I can't really figure out why the nodes[i] variables don't change?
That happens (probably) because the browser prints out the empty array but by the time you check it, it has content again. So when you click to expand the browser shows the actual content.
As you can see the values [1,3,7] were added after the command console.log(o) but they are shown on the screen (even though the length shown is 0).
You're not supposed to set the length field. Just re-initialize them:
nodes[i].outEdges = [];
nodes[i].inEdges = [];
Edit: My bad, setting the length should work. It does work for me on Chrome at least. However, I still think it's safer and better style to re-init.
Just create a new object with the same name
nodes[i].outEdges = new Array();

Categories