I'm confused by position and transaction

So I have the following document structure

<gallery>
<image src='xxx.png'></image>
...
</gallery>

gallery is an atom node, containing a list of images. Each image has an attribute src.

now given an index to one of the images, I want to change its src

let tr = new Transform(galleryNode.child(0));       
tr.setNodeAttribute( 0, 'src',  'new_src_location');
this.outerView.dispatch(tr);

This won’t work, and I got an error saying that the node at position 0 doesn’t have the attribute “src”.

if I operate on the gallery node instead, I will see no error

let tr = new Transform(galleryNode);       
tr.setNodeAttribute( 0, 'src',  'new_src_location');
this.outerView.dispatch(tr);

This would work (no errors), but after the operation, if I inspect the document, the attribute hasn’t been changed.

The document doesn’t explain what it means by Pos in the function setNodeAttribute

Don’t create transforms with some specific node as constructor argument. Start a state transaction (view.state.tr) and update the content of the entire document in that.

I changed my code to the following:

            let tr = this.outerView.state.tr.setNodeAttribute(this.getPos()+1, 'src', 'new_file_src');
            this.outerView.dispatch(tr);

This works, but I don’t know how to reliably get the position of a node’s position relative to its parent.

Here I’m using getPos() +1 to change the first child, but if I need to change the 5th child, How can I know its position? There doesn’t seem to be a function to return a node’s position. Am I missing anything? Thank you.

Count node sizes of the sibling nodes in front of the target, or use ResolvedPos.posAtIndex.

Thank you. it works now. just log my solution in case it can help others:

I get the parent’s resolvedPos first: then used posAtIndex:

let rpos=parentNode.resolve(0);

let tr = this.outerView.state.tr.setNodeAttribute( this.getPos() + 1 + rpos.posAtIndex(child_index, 0), 'attr',  'new_attr');