Getting a value from a collection after setting the entire collection returns 'undefined'
Describe the bug Getting a value from a collection after setting the entire collection returns 'undefined'
To Reproduce See nodeJS script below.
Expected behaviour Getting a value from a collection after setting the entire collection should return the correct/actual value, not undefined.
Versions (please complete the following information):
- Environment: nodeJS v16.16.0
yaml: v2.2.1
Additional context See script below.
// ----------------------------------------------------------------------------
// Using:
// - [email protected]
// - nodeJS v16.16.0
//
// Bug: Getting a value from a collection after setting the entire collection
// returns 'undefined'
//
// Summary of Steps:
// 1. Parse a document with a Seq collection
// 2. Get (getIn) the value of an entry in the Seq collection ... OK
// 3. Set the entire collection using 'set' or 'setIn'
// 4. Get (getIn) the value of an entry in the Seq collection again ... NOK (undefined)
// ----------------------------------------------------------------------------
const { parseDocument } = require('yaml')
const content = `
---
name: simulacrum
path: /opt/simulacrum
splunk:
- log_path: /var/log/simulacrum/access.log
index: apps_nonprod
sourcetype: generic_singleline
source: simulacrum-access
- log_path: /var/log/simulacrum/error.log
index: apps_nonprod
sourcetype: _json
source: simulacrum-error
`
// Parse the YAML
const doc = parseDocument(content)
// Print it out ... GOOD!
console.log(doc.toString())
// Get the splunk/0/log_path value
let logPath = doc.getIn(["splunk", 0, "log_path"])
// Print it out ... GOOD!
console.log(`==> OK logPath: ${JSON.stringify(logPath)} <== OK`)
// Use `set` or `setIn` to set the entire `splunk` collection
const newValue = [
{
log_path: "fish",
index: "fry",
sourcetype: "never",
source: "more"
}
]
// doc.set("splunk", newValue)
doc.setIn(["splunk"], newValue)
// Print it out ... GOOD!
console.log(doc.toString())
// Get the `splunk` section
const splunk = doc.get("splunk")
// Print it out ... GOOD
console.log(`splunk: ${JSON.stringify(splunk)}`)
// Get the splunk/0/log_path value (same as above)
logPath = doc.getIn(["splunk", 0, "log_path"])
// Print it out ... BAD!
// The value of `logPath` is `undefined`
// ...`logPath` should be `fish`
console.log(`==> NOK logPath: ${JSON.stringify(logPath)} <== NOK, undefined`)
Not sure is this is a work-around or intended behavior, but if I create newValue using the createNode method everything works as expected:
const newValue = doc.createNode(
[
{
log_path: "fish",
index: "fry",
sourcetype: "never",
source: "more"
}
]
)
If setting a collection using a "raw" Object/Array is NOT suppose to work, then you have my apologies and can close this issue.
This currently counts as intended behaviour. The get/set methods were added mostly as sugar for the direct access modification of the node tree, which supports having plain JS values embedded in it. This means that the setIn() doesn't apply doc.createNode() on the value that's set, and that getIn() doesn't navigate through non-node objects.
Changing the former would be a breaking change, but the I think the latter could be extended as a non-breaking change, along with #386.