1

Every time I try to access a deep level property (I guess an item in an array through it's index) I get the following error:

ERROR TypeError: Cannot assign to read only property 'value' of object '[object Object]'

Find below the code I'm trying to get running, but will throw the error above:

@Input() data: CivilLiabilityQuestionnaireModel;
public questions: CivilLiabilityQuestionnaireModel;

this.questions = { ...this.data };

const questionGroupIndex = 0;
const questionGroupItemIndex = 0;

this.questions
    .questionGroup[questionGroupIndex]
    .questionGroupItems[questionGroupItemIndex]
    .answers[0]
    .value = form[val];

A little more details of what's possible:

// This works
this.questions.id = 'hotdog';

// This doesn't work
// ERROR TypeError: Cannot assign to read only property 'id' of object '[object Object]'
this.questions.questionGroup[questionGroupIndex].id = 'hamburger';

I thought this would only be possible with using the spread operator, but this will turn all my arrays into objects, while I need to keep my arrays at any cost.

Here the spread solution I tried:

this.questions = {
  ...this.questions,
  questionGroup: {
    ...this.questions.questionGroup,
    [questionGroupIndex]: {
      ...this.questions.questionGroup[questionGroupIndex],
      questionGroupItems: {
        ...this.questions.questionGroup[questionGroupIndex].questionGroupItems,
        [questionGroupItemIndex]: {
          ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex],
          answers: {
            ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex].answers,
            [0]: {
              ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex].answers[0],
              value: form[val]
            }
          }
        }
      }
    }
  }
};
Jordec
  • 1,516
  • 2
  • 22
  • 43
  • 2
    It seems like the properties you try to change are [defined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) as read-only. So I don't think it's *nesting* that's the issue but instead the objects themselves. – VLAZ Apr 25 '19 at 08:42

2 Answers2

2

I managed to find the solution to the problem. In my example from the original question I did the following:

this.questions = { ...this.data };

The solution came from another post: https://stackoverflow.com/a/40922716/2664414

The issue with the example above is that you only make a clone of the root property, while the nested child properties remain frozen.

Since my value came from the NGRX store, it's basically in a "freeze" state and can't be adjusted.

To fix this, you can use cloneDeep() from lodash to make sure the nested properties get cloned aswell and lose the "freeze" state.

this.questions = _.cloneDeep(this.data);
Jordec
  • 1,516
  • 2
  • 22
  • 43
0

Maybe you defined something somewhere as constant and you're trying to change it. Javascript does not support read only props naturally so basically in practice the only reason to get this error is that you either defined some variable/prop as constant or you defined a obj's prop as writable=false and you're trying to change it. Look for questionGroupIndex or questionGroupItemIndex you might be trying to change them. Either way the problem is not in the nesting.

Yosif Mihaylov
  • 108
  • 1
  • 9
  • I traced everything back and there are no (more) constants defined, not are the `questionGroupIndex` or `questionGroupItemIndex` changing. I also tried adding using the value of the index directly (`...questionGroup[0]...`) but no result. – Jordec Apr 25 '19 at 09:18