1

I have what seems like it should be a simple operation. For each bridgedSection, I check for a potentialSection with an id that matches the bridged.referenceSection

Then I take that result, parse the HTML on the object with Cherio, make a slight modification (using an id for testing), and then store both the bridgedSection and the modified result on an object, then push that object to the array.

If I log the new object BEFORE pushing, I get the correct object values. If I log it from the array I get incorrect values only for reference.section. bridgedSection is fine, but reference.section matches across all entries in the array.

To say that I'm thoroughly flummoxed is an understatement. Can anyone shed some light on what I am (clearly) doing wrong?

var sectionCount = 0;
bridgedSections.forEach(bridged => {
    var obj = potentialSections.find(obj => obj._id == bridged.referenceSection);

    $ = cheerio.load(obj.html);
    $(".meditor").html(bridged._id);// dropping the id here so it's easy to see if it was updated

    obj.html = $.html();
    obj.rand = Math.floor(Math.random() * 1000); // can't seem to add to obj either

    var thisSection = {
        referenceSection: obj,
        bridgedSection: bridged,
    }
    console.log(thisSection) // correct value logged
    currentSections.push(thisSection);
    sectionCount++;
});
console.log(currentSections); 
// this logs an array of the correct length but each 
// {}.referenceSection is identical to the last entry pushed above
  • 2
    When you find the object in `potentialSections`, nothing in your code makes copies of the objects. Thus there may be multiple references to the same objects spread around. – Pointy Nov 06 '18 at 13:13
  • Of course! Thank you haha. –  Nov 06 '18 at 13:34

3 Answers3

1

Javascript is passes function parameters by reference. This means the following happens:

derp = {a:1}
function passedByRef(param){
  param['a'] = 2;
}
passedByRef(derp)
console.log(derp['a']) // 2

So when you pass a json object to a function, if you modify said object in the function it will change the original object. You probably want to make a deep copy of bridged before you assign it to thisSection because if you modify the version of bridged later on in thisSection it will modify the original object.

Here is a post that talks about cloning objects or you could look into something like immutable js

unflores
  • 1,764
  • 2
  • 15
  • 35
  • Maybe I'm not clear enough in my response. The reason something is unexpectedly being modified is due to javascript passing parameters by reference. The use can avoid that by copying the object bridged. They'll most likely need to make a deep copy of the object. I can reword my answer a little to clarify. – unflores Nov 06 '18 at 16:40
1

To try to clarify what both of the above folks are saying, the JavaScript language (like many others) has the concept of references, and makes very heavy use of that concept.

When one variable "refers to" another, there is only one copy of the value in question: everything else is a reference to that one value. Changes made to any of those references will therefore change the [one ...] underlying value (and, be reflected instantaneously in all of the references).

The advantage of references is, of course, that they are extremely "lightweight."

If you need to make a so-called "deep copy" of an array or structure or what-have-you, you can do so. If you want to push the value and be sure that it cannot be changed, you need to make sure that what you've pushed is either such a "deep copy," or that there are no references (as there obviously are, now ...) to whatever it contains. Your choice.

N.B. References – especially circular references – also have important implications for memory management (and "leaks"), because a thing will not be "reaped" by the memory manager until all references to it have ceased to exist. (Everything is "reference counted.")

And, all of what I've just said pretty much applies equally to every language that supports this – as most languages now do.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
0

I think you need to look into Javascript deep copy.

You are modifying the original object when you modify the second assigned variable, because they are pointing to the same object. What you really need is to duplicate the object, not simply making a pointer to it.

Take a look at this:

https://scotch.io/bar-talk/copying-objects-in-javascript#toc-deep-copying-objects

Steven McConnon
  • 2,650
  • 2
  • 16
  • 21