-1

I came across this weird behavior in my code, where i am updating a single property of a nested object within an array of objects. Weirdness is that the same property for all similar objects is getting updated.

Code:

let financials = {
  qr: {
    controlData: [
      {
        "year": "2013",
        "quarters": [
          {
            "month": "Mar",
            "name": "first",
            "alias": "Q1",
            "isChecked": true
          },
          {
            "month": "Jun",
            "name": "second",
            "alias": "Q2",
            "isChecked": true
          },
          {
            "month": "Sep",
            "name": "third",
            "alias": "Q3",
            "isChecked": true
          },
          {
            "month": "Dec",
            "name": "fourth",
            "alias": "Q4",
            "isChecked": true
          }
        ]
      },
      {
        "year": "2014",
        "quarters": [
          {
            "month": "Mar",
            "name": "first",
            "alias": "Q1",
            "isChecked": true
          },
          {
            "month": "Jun",
            "name": "second",
            "alias": "Q2",
            "isChecked": true
          },
          {
            "month": "Sep",
            "name": "third",
            "alias": "Q3",
            "isChecked": true
          },
          {
            "month": "Dec",
            "name": "fourth",
            "alias": "Q4",
            "isChecked": true
          }
        ]
      },
      {
        "year": "2015",
        "quarters": [
          {
            "month": "Mar",
            "name": "first",
            "alias": "Q1",
            "isChecked": true
          },
          {
            "month": "Jun",
            "name": "second",
            "alias": "Q2",
            "isChecked": true
          },
          {
            "month": "Sep",
            "name": "third",
            "alias": "Q3",
            "isChecked": true
          },
          {
            "month": "Dec",
            "name": "fourth",
            "alias": "Q4",
            "isChecked": true
          }
        ]
      }
    ]
  }
};

$('.checkbox.quarterly').click(function (e) {
    try {
        // var selectedYear = $('.dropdown.quarterly').dropdown('get value');
        // var month = $(this).find('.checkbox-input').data('month');
        // var prop = $(this).find('.checkbox-input').prop('checked');
        // var targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });

        // Values assumed
        var selectedYear = '2013';
        var month = 'Mar';
        var prop = false;
        var targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });

        $.each(targetObj.quarters, function (key, quarter) {
            if (quarter.month === month) {
                quarter.isChecked = prop;
            }
        });
    } catch (ex) {
        console.log(ex);
    }
});

Actual Output:

controlData: [
  {
    "year": "2013",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": false
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  },
  {
    "year": "2014",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": false
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  },
  {
    "year": "2015",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": false
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  }
]

Expected Output:

controlData: [
  {
    "year": "2013",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": false
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  },
  {
    "year": "2014",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": true
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  },
  {
    "year": "2015",
    "quarters": [
      {
        "month": "Mar",
        "name": "first",
        "alias": "Q1",
        "isChecked": true
      },
      {
        "month": "Jun",
        "name": "second",
        "alias": "Q2",
        "isChecked": true
      },
      {
        "month": "Sep",
        "name": "third",
        "alias": "Q3",
        "isChecked": true
      },
      {
        "month": "Dec",
        "name": "fourth",
        "alias": "Q4",
        "isChecked": true
      }
    ]
  }
]

Basically what i was trying to do is, to update the property 'isChecked' of a particular month whenever I click on the corresponding checkbox. My project is running on Laravel Mix with Webpack.

UPDATE:

This is how the controlData is being created:

let years = ['2013', '2014', '2015'];

let quarters = [
    {
        month: 'Mar',
        name: 'first',
        alias: 'Q1',
        isChecked: true
    },
    {
        month: 'Jun',
        name: 'second',
        alias: 'Q2',
        isChecked: true
    },
    {
        month: 'Sep',
        name: 'third',
        alias: 'Q3',
        isChecked: true
    },
    {
        month: 'Dec',
        name: 'fourth',
        alias: 'Q4',
        isChecked: true
    }
];

for(let x in years) {
    let obj = {
        year: years[x],
        quarters: quarters
    };

    financials.qr.controlData.push(obj);
}
Pradeep Vig
  • 485
  • 6
  • 7

2 Answers2

0

For me it seems to works just fine. Only the value for Mar 2013 is getting set to false.

Underscore v1.8.3
jQuery v3.3.2

https://jsfiddle.net/7o1tx49d/4/

Lumpenstein
  • 1,250
  • 1
  • 10
  • 27
  • 1
    I think i've got the problem here but an explanation will enlighten me. Just look at the way i am creating the controlData. Thanks. – Pradeep Vig Nov 05 '18 at 08:45
  • "Works for me" is a comment, not an answer. I believe you need 50 rep to comment, you're not far off. – freedomn-m Nov 05 '18 at 09:40
  • Yes I need 50 rep, couldn't comment :/ Indeed the problem comes from the shallow copies. See https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object – Lumpenstein Nov 05 '18 at 11:01
0

You create independent arrays with independent objects by mapping copies of the objects.

financials.qr.controlData = years.map(year => ({
    year,
    quarters: quarters.map(o => Object.assign({}, o))
}));

var financials = { qr: {} },
    quarters = [{ month: 'Mar', name: 'first', alias: 'Q1', isChecked: true }, { month: 'Jun', name: 'second', alias: 'Q2', isChecked: true }, { month: 'Sep', name: 'third', alias: 'Q3', isChecked: true }, { month: 'Dec', name: 'fourth', alias: 'Q4', isChecked: true }],
    years = ['2013', '2014', '2015'];

financials.qr.controlData = years.map(year => ({
    year,
    quarters: quarters.map(o => Object.assign({}, o))
}));

var selectedYear = '2013',
    month = 'Mar',
    prop = false,
    targetObj = _.findWhere(financials.qr.controlData, { year: selectedYear });

$.each(targetObj.quarters, function (key, quarter) {
    if (quarter.month === month) {
        quarter.isChecked = prop;
    }
});

console.log(financials);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392