How to insert text with decorations?

I try to insert an array of text programmatically by

const changes = changes
  .map(({ from, content }) => ({ from, insert: content }))

view.dispatch({ changes })

It works. However, I would also like to decorate these inserted text. Here is what I do:

const effects = changes
  .map(({ from, to }) => addAdd.of({ from, to }))

view.dispatch({ effects })

However, it doesn’t work. I guess it is because the { from, to} is the position of the old doc (before inserting the content). They can be used to insert the text but cannot be used to set the range of the decoration. am I correct? how should I fix this?
Thanks!

The fact that const changes = changes.map(...) isn’t valid JavaScript makes it a bit hard to see what you are really doing. But I assume in your code those are two different variables, and the one you use in the computation of effects isn’t the one you define above.

If you use view.state.changes to create a ChangeSet object for your changes (which you can also dispatch), you can use that to map positions from the document space before the change to after. Also probably makes sense to dispatch both the changes and the decorations in a single transaction.

Thank you @marijn

Sry for the typo, the correct code should be

const changes = rawChanges
  .map(({ from, content }) => ({ from, insert: content }))

view.dispatch({ changes })

const effects = rawChanges
  .map(({ from, to }) => addAdd.of({ from, to }))

view.dispatch({ effects })

Are you suggesting

const changes = rawChanges
  .map(({ from, content }) => view.state.changes({ from, insert: content }))

const effects = changes
  .map(rawChanges)
  .map(({ from, to }) => addAdd.of({ from, to }))

view.dispatch({ effects, changes })

No, I’m not, because that code makes zero bloody sense (you’re using an array as a map function?).

let changes = view.state.changes(rawChanges.map(
  ({from, content}) => ({from, insert: content}))
let effect = addAdd.of(rawChanges.map(
  ({from}) => ({from: changes.mapPos(from, -1), to: changes.mapPos(from, 1)}))
view.dispatch({changes, effects})

ah I see what you mean. I took my changes as a changeSet and use it map function.

Thank you!