0

I have a multidimensional object and using Vue, I am trying to make the inner object reactive.

My object looks like this:

data() {
   return {
       myObject: {}
   }
}

And the filled data looks like this:

myObject: {
   1: {         // (client)
     0: "X",    // (index) : (value)
     1: "Y"
   },
   2: {
     0: "A",
     2: "B"
   }
}

If I try using:

let value = "X";
let client = 1;
let index = 1;

let obj = {};
obj[client][index] = value;
this.myObject = Object.assign({}, this.myObject, obj);

It throws an error:

TypeError: Cannot set property '0' of undefined

And if I try below, it overwrites the initial values as it is initially setting the object to {}

let obj = {};
obj[index] = value;
let parentObj = {};
parentObj[client] = obj;
this.myObject = Object.assign({}, this.myObject, parentObj);

What is the proper way of adding the values to the multidimensional object?

2 Answers 2

1

In javascript, dim2Thing[1][1] = ... expressions require dim2Thing[1] to exist. This is why you get the error you mentioned. So you can do two expressions, which should work fine:

dim2Thing[1] = dim2Thing[1] || {} dim2Thing[1][1] = otherThing

For the last block, you mention that it "overwrites the initial values"

I think what's actually happening here is just that Object.assign is not recursive. It only merges top-level keys. So if parentObj has a key that over-laps with this.myObj, then sub-keys will be lost.

Object.assign({ a: { b: 2} }, { a: { c: 3 } }) // returns { a: { c: 3 }  }

This is what I interpret your code as trying to do - though I am unfamiliar with vue.js at this time, so I cannot assure it will have the desired result to your webpage:

let value = "X";
let client = 1;
let index = 1;

const newObj = Object.assign({}, this.myObject);
// if you have lodash _.set is handy
newObj[client] = newObj[client] || {}; // whatever was there, or a new object
newObj[client][index] = value
this.myObject = newObj
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for giving me the perspective of || {}
0

Just use an array, thats reactive by design. If you need to get elements from the array in your template or anywhere just add a find method

// temp

late
<div v-for="(value, idx) in myArray">{{find(obj => obj.id === idx)}}</div>

methods: {
  find (searchFunction) {
    return this.myArray.find(searchFunction)  
  }
}

1 Comment

Thanks for your input. Due to the design of my structure, I can't use arrays but otherwise .find would work like charm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.