Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problems mutating array between several methods: Returned value always reference old values

I have an object with several methods that looks like this:

export const myObject = {
  method1: function (arr, value) {
    this.method2(arr, value)
    this.method3(arr).filter(item => item === 'something')
  },
  method2: function (arr, value) {
    if (true) {
      value = 'change this value'
      if (true) {
        value = 'then change this'
        arr = [...arr.slice(0, -1)]
      }
    }
    arr = [...arr, value]
    return arr
  },
  method3: function (arr) {
    switch(arr.at(-1)) {
      case 1:
        arr = [...arr, 2]
        break
      case 2:
        arr = [...arr, 1]
        break
      default:
        arr = [...arr]
    }
    return this
  },

My problem is when I call method2 from method1, I receive the same reference and not the mutated array. If I put console logs in my code I can actually see the changes:

myObject = {
  method1: function (value) {
    console.log('here my value is 10')
    this.method2(value)
    console.log('here my value is 10 again')
  },
  method2: function (value) {
    value = value + 10
    console.log('here my value is 20')
    return value
    console.log('see second log in method 1')
  },

I’ve already tryed changing variable names, and using different ways to insert the old values in the array but always have the same problem: the returned value is the original array.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

My method2 it works because I’m using with several components in the app, the problem is when I call this method from a sibling method, regarding method3, I can place that function inside method1 because isn’nt needed in any other place, but method2 as I said is reused in other components.

What I’m doing wrong here? Please sorry if I’m not clear this is my first post in the community, you have the related code here and the working app here: React Calculator

>Solution :

Javascript parameters are always passed by value. You can change properties of the value you pass in, and those changes will be visible to the calling method. But if you change the parameter to point to a different reference, that change will not be visible to the calling method.

For example:

function A(arr) {
    arr[0] = 42;
    console.debug("Inside A", arr);
    // Output: [42, 1, 2, 3]
}

function B(arr) {
    arr = arr.slice(1);
    console.debug("Inside B", arr);
    // Output: [1, 2, 3]
}

let x = [0, 1, 2, 3];
console.debug("Initial", x);
// Output: [0, 1, 2, 3]

A(x);
console.debug("After A", x);
// Output: [42, 1, 2, 3]

B(x);
console.debug("After B", x);
// Output: [42, 1, 2, 3]

The changes made by A are visible outside of the function, because it simply changes a property on the object that was passed in.

The changes made by B are NOT visible outside of the function, because it reassigned the parameter to refer to a different object instance.

In your example, you can get the updated array by using the return value of method2:

method1: function (arr, value) {
    arr = this.method2(arr, value);
    this.method3(arr).filter(item => item === 'something')
}

However, you cannot get the updated array out of method3.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading