0

I created variable bpJson, and am not understanding why it is changing. I am console logging it every 5 seconds, and it changes each iteration. I only expected babyPieData to change while bpJson stays the same each time. There is no bpJson in setPieOptions so I did not include the code for that function.

var createVariance = function(bpJson, babyPieData){
    var n = bpJson.length;
    for ( var i = 0; i < n; i++){
        var amount = Math.floor(Math.random() * 4);
        var operator = Math.floor(Math.random() *2) + 1;
        if (operator === 1){
            babyPieData[i] = (bpJson[i] + amount);
            if (babyPieData[i] > 100){
                babyPieData[i] = 100;
            }
        }else{
            babyPieData[i] = (bpJson[i] - amount);
            if (babyPieData[i] < 0){
                babyPieData[i] = 1;
            }
        }
        setPieOptions(babyPieData);
    }
};

var getBabyPieData = function(){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'php/baby-pie.php');
    xhr.send();
    xhr.onload = function(){
        var babyPieData = JSON.parse(xhr.response);
        console.log('original babyPieData = ' + babyPieData);
        var bpJson = babyPieData;
        setPieOptions(babyPieData);
        var babyPieDataTimer = window.setInterval(function(){
            createVariance(bpJson, babyPieData);
            console.log(bpJson);
        }, 5000);
    };
}();
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Off topic because "why isn't this code working." – bhspencer Jun 14 '16 at 16:46
  • @bhspencer ?? What does that mean? This is a question about some code, and the code is posted. – Pointy Jun 14 '16 at 16:50
  • One of the reasons for closing a question is 'Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example.' – bhspencer Jun 14 '16 at 16:52
  • 1
    @bhspencer yes, I'm familiar with that. This question is fine. – Pointy Jun 14 '16 at 16:53
  • The question as stated is not a "Minimal, Complete, and Verifiable example". This question is never going to be useful to other readers in its current form and shoudl be closed. – bhspencer Jun 14 '16 at 16:53
  • 2
    @bhspencer if that standard were consistently applied, about 90% of the questions on the site would be closed. This question contains a clear statement of the problem and all the code necessary to provide an answer. – Pointy Jun 14 '16 at 16:55
  • So you are claiming that the above code is the "shortest code necessary to reproduce" the problem. The OP has not made any effort to provide a Minimal, Complete, and Verifiable example. All they have done is dump their broken code on the site and complain that it isn't working. – bhspencer Jun 14 '16 at 16:57
  • 2
    Duplicate? [Why does changing an Array in JavaScript affect copies of the array?](http://stackoverflow.com/q/6612385/218196). Though T.J.'s answer is much nicer... – Felix Kling Jun 14 '16 at 17:00
  • 1
    @bhspencer I don't know how often you answer web development (JavaScript, CSS, etc) questions, but many participants don't have anywhere close to sufficient experience or technical depth to actually fulfill that rule to any significant degree. It'd make life a lot easier if that were not the case, but that's the situation. I edited the question title to hopefully make it a little better of a search target. – Pointy Jun 14 '16 at 20:09
  • @bhpspencer - I placed that code there in the event it was causing my variable to change and I was simply unaware. I did not include the code for setPieOptions as I stated in the question, as there was no instance of bpJson in there, so I did minimize it leaving what I thought would be relevant. I only posted what I thought would be necessary to let me know what I was doing wrong, and it was answered and I learned from it. –  Jun 14 '16 at 21:05
  • @Pointy I have done a fair bit of answering of JavaScript web dev questions and I do find that many, perhaps the majority, do not satisfy the quality rules for a question on SO. Personally I think it best to tell new SO users that their questions are not good enough and vote to close rather than dilute the quality of the content on SO. – bhspencer Jun 14 '16 at 22:47

3 Answers3

4

From your code, it's clear that you're using an object; it looks like it's probably an array.

Variables don't directly contain objects like arrays, they contain references to them; the actual object is elsewhere. You could picture it as the variable having a number in it which tells the JavaScript engine where to find the object:

+−−−−−−−−−−−−−+             
| babyPieData |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:123456  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+

So the issue is that this line doesn't do what you think it does:

var bpJson = babyPieData;

That doesn't create a copy of the array. It just creates a second copy of the reference to the array. Both variables still refer to (point to) the same array:

+−−−−−−−−−−−−−+       
| babyPieData |       
+−−−−−−−−−−−−−+       
| Ref:123456  |−−−−−−+
+−−−−−−−−−−−−−+      |
                     |
                     |      +−−−−−−−−−+
                     +−−−−−>| (Array) |
+−−−−−−−−−−−−−+      |      +−−−−−−−−−+
| bpjSon      |      |      | 0: 42   |
+−−−−−−−−−−−−−+      |      | 1: 67   |
| Ref:123456  |−−−−−−+      +−−−−−−−−−+
+−−−−−−−−−−−−−+             

If you want to copy the array, you'll need to do that on purpose. If the array contains simple values (as it appears to), you can do that like this:

var bpJson = babyPieData.slice();

slice with no arguments creates a shallow copy:

+−−−−−−−−−−−−−+             
| babyPieData |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:123456  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+
+−−−−−−−−−−−−−+             
| bpJson      |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:554654  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    I was not aware that a variable was simply a reference to the object. Your explanation was incredibly helpful in helping me to understand why the code was not working and much appreciated. –  Jun 14 '16 at 17:21
  • @Mike: Glad that helped! Yes, variables do directly contain the values of primitives like numbers and booleans (in the standard interpretation of them, anyway), but for objects (including arrays) it's a value (like a number) that's a reference. – T.J. Crowder Jun 14 '16 at 17:38
2

Because bpJson and babyPieData are the same object.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • 3
    Please consider closing a question that is off topic because "why isn't this code working." rather than writing a one line answer. – bhspencer Jun 14 '16 at 16:47
  • 2
    @bhspencer this question is not off-topic. It contains the code with the problem, and it contains a description of the problem. It's not the greatest question ever, perhaps, but there's enough to see the problem and provide an answer. – Pointy Jun 14 '16 at 16:52
-1

"How to clone a js object elegantly"

as already stated by @Scott "Because bpJson and babyPieData are the same object." Follow the link to create an independent copy of any js object, not specifically an array.

Community
  • 1
  • 1
Himanshu
  • 490
  • 1
  • 8
  • 17