Transaction not beeing applied

I have two realization with different approach but with almost the same code inside. but checkAnswer is working, checkAnswer2 is not

they are iterating through children of node and changes attributes of nodes particular type

checkAnswer2() {
  const from = this.getPos();
  const to = from + this.node.nodeSize;
  this.editor.state.doc.nodesBetween(from, to, (node) => {
    if (node.type.name === this.extension.options.inputNodeName) {
      let classes = '';
      if (node.attrs.value) {
        classes = node.attrs.answers.includes(node.attrs.value) ? 'success' : 'error';
      }
      const position = node.attrs.position;
      // const position = pos;
      node.attrs.classes = classes;
      const newAttrs = { ...node.attrs, classes: classes };
      this.editor.view.state.tr.setNodeMarkup(position, undefined, newAttrs);
    }
  });
},
checkAnswer(node) {
  if (!node?.content?.content?.length) {
    if (node.type.name === this.extension.options.inputNodeName) {
      this.checkFillGapsInput(node);
    }
  }

  // проверяем потомков рекурсивно
  if (node?.content?.content?.length) {
    node.content.content.forEach((node) => this.checkAnswer(node));
  }
},
checkFillGapsInput(node) {
  let classes = '';
  if (node.attrs.value) {
    classes = node.attrs.answers.includes(node.attrs.value) ? 'success' : 'error';
  }
  const position = node.attrs.position;
  node.attrs.classes = classes;
  this.editor.view.state.tr.setNodeMarkup(position, undefined, node.attrs);
},

first one runs all the children recursively and checks if its the node type we need, second uses nodesBetween where it takes getPos() as a begin and getPos() + nodeSize as the end

A transaction only has an effect when you dispatch it. In this line, you are creating one but then doing nothing with the object.

Thanks for reply, Marijn!

Now I tried

this.editor.view.dispatch(this.editor.view.state.tr.setNodeMarkup(position, undefined, newAttrs));

also

this.editor.dispatchTransaction(this.editor.view.state.tr.setNodeMarkup(position, undefined, newAttrs));

but it did not work

But even if the reason is the transaction not beeing dispatched why it worked in first function where were no dispatch at all?

I noticed that in first function window.MutationObserver is triggered to rerender DOM, but in the second function editor state is kinda beeing updated but its not triggering browser DOM to update

Запись экрана 2023-07-20 в 15.50.28

here you can see that it does not checks the spelling at first time but when I trigger update data by new input it updates the class attribute and then get highlighted with green

second input the same, at first I filled the wrong answer, but right after the Check button it did not highlight red color, only after triggering state

That definitely did nothing as well. Maybe your conclusion that it did was mistaken.

Also, you appear to be mutating data you shouldn’t mutate (node.attrs.classes) which could add the the confusion.

  1. may be, but how is it possible that the classes were applied
  2. mutating the classes is the idea of the parent node, It has the “check answers” button, it iterates through child nodes of particular type and checks if the value of input is allowed

Coul you please explain the idea why I shouldnt chang node’s inner attributes from other one?

If you try to use this library without reading the docs, you’re going to have a terrible time. For this specific issue, see this section.

1 Like

Thanks for reply, Marijn!

I understand that I shouldn’t mutate node.attrs properties directly. But changing them via transaction.setNodeAttribute or transaction.setNodeMarkup is okay, right? Just don’t forget to dispatch it.

If suggestion above is correct is it okay to update attributes of child nodes with setNodeAttribute method from parent node?