Your 2nd example dynamically creates (link:) macro calls that have a structure like the following
(link: "Buy")[
(set: $selected to "ItemA")
(set: _item's Quantity to 1)
(go-to: "next")
]
The _item temporary variable referenced in the above was declared within the local scope of the (for:) macro associated hook, which means that that temporary variable no longer exisits once the (for:) macro has finished. This is why selecting any of the generated links results in an error.
There are a number of ways to get around this issue, one of the easiest is to change your $items story variable to have a Key & Value structure like the following
(set: $items to (dm:
"itemA", (dm: "Name", "Item A", "Price", 13000, "Quantity", 1),
"itemB", (dm: "Name", "Item B", "Price", 2000, "Quantity", 1)
))
... which associates a Key (the "itemA" & "itemB" strings) with each Value (the item data-maps). This means you only need to pass the relevant Key to the "next" passage to know which item was selected.
WARNING: HTML table elements are expensive to create, which is why modern Web Developers use them sparingly when creating page layout. For this reason I have replaced the table elements in your example with div elements.
Your (for:) macro call would now look like the following
(for: each _id, ...(datanames: $items))[
<div style="display: inline-block;">
<br>(print: $items's (_id)'s Name)
<br>(print: $items's (_id)'s Price)
<br>(print: '(link: "Buy")[(set: $selected to "' + _id + '")(go-to: "next")]')
</div>
]
... and you can test the above by adding code like the following to the start of your "next" passage.
Selected Item: (print: $items's ($selected)'s Name)
NOTE: Valid CSS property values are meant to end with a semi-colon.
eg. display: inline-block;