Google Script: Unable to assign a value to a specific key within an object

My JavaScript object structure involves years as keys and months inside them to store information. The initial object looks like this:

function generateYearMonths() {
  var firstYear = 2012;
  var todayDate = new Date(Date());
  var lastYear = todayDate.getYear();
  var yearsMonths = {}

  var months = {}

  for(var x=1; x<=12; x++) {
    months[x.toString()] = {
      totalExpenses: 0,
      totalIncomes: 0,
      totalBalance: 0
    }
  }

  for(var x=firstYear; x<=lastYear; x++) {
    yearsMonths[x] = months
  }

  return yearsMonths;
}

I am trying to set a value for a specific year and month combination, such as 2012 for year and 1 for month. I attempted the following:

yearsMonths[2012][1]["totalExpenses"] = 23;

However, the value 23 gets assigned to every month in the year 2012's object. I can't figure out what mistake I'm making. This is my first time working with Google script and I just want to update specific key-value pairs without overwriting everything.

Your assistance would be greatly appreciated.

EDIT -- Restructuring months within the loop for each year

function generateYearMonths() {
  var firstYear = 2012;
  var todayDate = new Date(Date());
  var lastYear = todayDate.getYear();
  lastYear = 2013;
  var yearsMonths = {}

  for(var x=firstYear; x<=lastYear; x++) {

    var months = {}

    for(var x=1; x<=12; x++) {
      months[x.toString()] = {
        totalExpenses: 0,
        totalIncomes: 0,
        totalBalance: 0
      }
    }
    yearsMonths[x] = months
  }

  return yearsMonths;
}

By moving the month creation logic inside the yearly loop, I no longer encounter infinite loops while assigning values individually for each month.

Answer №1

In the world of Javascript, objects are passed by reference rather than by value. This means that when you declare var months = {}, you are actually referencing the same object throughout your entire script. So, every time you loop through and do:

for(var x=firstYear; x<=lastYear; x++) {
  yearsMonths[x] = months
}

Each yearMonths[x] is pointing to the exact same single months object. To create unique references for each item in the yearMonths array, you need to perform a deep clone of the months object like this:

for(var x=firstYear; x<=lastYear; x++) {
  yearsMonths[x] = JSON.parse(JSON.stringify(months));
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JQuery spinner not triggering OnChange event for Input Type = Number

I am dealing with an <input type="number" class="post-purchase-amount"/>. Currently, I have implemented an ajax call that triggers when the value is changed. It works perfectly fine when I manually change the value by typing in the text box. Howeve ...

The jspdf function is not displaying any images in the PDF file

I am new to coding and encountered an issue when trying to download images in reactjs. After clicking the download button, I only receive a blank pdf file. https://i.stack.imgur.com/0XJcC.png The function in my react code that attempts to generate the p ...

jQuery functions do not have any impact on newly appended elements

Why are jQuery functions not affecting appeneded elements after ajax? I am aware of two possible solutions, but neither seems optimal. Firstly, when I append an element, I also re-append the jQuery functions each time. This means that for every appended ...

What is the process for implementing a Content Security Policy to enable the loading of external JS files from a CDN in ExpressJS?

When working with ExpressJS, the HTML file is loaded in the following manner: app.use(express.static(__dirname + '/src/templates/')); Within the HTML file, here is an example of a meta tag containing Content Security Policy: <meta http-equiv= ...

I have encountered an issue where after declaring a JavaScript variable on a specific page, including the JavaScript file does not grant access to it

<script type="text/javascript"> $(document).ready(function () { var SOME_ID= 234; }); </script> <script type="text/javascript" src="<%= HtmlExtension.ScriptFile("~/somefile.js") %>"></script> ...

Clicking on an Angular routerLink that points to the current route does not function unless the page is re

Currently, I am working on an E-commerce project. In the shop page, when a user clicks on the "View More" button for a product, I redirect them to the product details page with the specific product id. <a [routerLink]="['/product-details' ...

How do I locate the scope of a controller that has been loaded in AngularJS?

How can I find the scope of a loaded controller? I want to trigger an event after the scope is initialized in order to predefine the model for the view. Is there a way to listen for $rootScope.$on("$controllerLoaded") ...

Turn on Orientation in UIWebview during Javascript Evaluation

As I begin assessing the javascript, such as when a user selects text and it becomes highlighted, I encounter issues with the device orientation on my iPad. The orientation stops working until the javascript finishes executing. Is there a way to manage ja ...

What is the best way to choose a tag from an app within components or views?

In my main component file, I added a color picker input in the navigation section to change the background color of the application. This works fine as the body tag can be accessed easily within the DOM. Furthermore, I store the selected color in local st ...

What is the process for refreshing information in VueJS?

<script> export default { data() { return { data: {}, dataTemp: {} } }, methods: { updateData() { let queries = { ...this.$route.query } this.data = { ...this.data, pID: queries.pid, s ...

What is the best way to record data while initiating a process in node.js?

In my latest project, I have implemented a function that spawns a process and requires logging specific information to the console. Here is an example of how this function is structured: function processData(number) { var fileName = settings.file || "de ...

discord.js-commando encountered an error: unable to find the fetchUser function

After successfully coding a discord bot on my personal computer using nodejs and discord.js-commando, I decided to transfer it to my Raspberry Pi 3b. I installed the latest version of nodejs, used scp to transfer the files, but encountered an error when tr ...

Acquiring the Firebase Cloud Messaging token within a React Native environment

As a beginner in the world of react native, I am exploring how to incorporate background notifications into my app. After conducting some research, it seems like using Firebase Cloud Messaging would be the most suitable approach for this. After going thro ...

Using d3 to showcase pictures sourced from a csv file

Having recently embarked on a journey to learn javascript, d3, and the polymer project, I am facing a challenge that I hope to get some guidance on. After successfully parsing a csv file containing image information and creating an array specifically for ...

Guide to utilizing axios.request(config) in Vue.js

I have been attempting to use Axios in my vue.js project to make HTTP requests. Despite reviewing the Axios documentation on GitHub and exploring various examples online, I have yet to find a solution. My goal is to create a configuration file where I can ...

How can objects be outlined in a projected context using a shader?

I am currently experimenting with modifying the OutlinePass in threejs to create outlines of connected objects in clip space (after applying the projection matrix). While these objects may appear separate in 3D space, they are considered connected after pr ...

In what way can I fill out my search fields using the criteria included in the URL?

In the process of developing an asp.net web application, I have implemented a code snippet to construct a section for search fields. This code builds URL parameters based on user input: <script type="text/javascript> $(document).ready(function(){ ...

Proceed with another ajax request only when the previous one has been successfully completed and loaded

While scrolling down and loading content into my page, I am facing an issue. The ajax executions load too quickly, causing the subsequent calls to not receive correct information from the first ajax call that is loaded into the DOM. How can I ensure that ...

Obtain an individual item from the reducer array

I am working on a company reducer that will store an array of companies. To optimize performance, I aim to fetch only the necessary company object from my API when a user navigates to /company/name. This way, if a user visits the same company page multiple ...

First render does not define useEffect

Why am I experiencing an issue here? Whenever I attempt to retrieve data from my API, it initially returns undefined during the first render, but subsequent renders work correctly. const [data, setData] = useState([]) useEffect(() => { const fe ...