Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

how to handle undefined values cleanly? #571

Closed
dcsan opened this issue Jul 25, 2020 · 5 comments
Closed

how to handle undefined values cleanly? #571

dcsan opened this issue Jul 25, 2020 · 5 comments

Comments

@dcsan
Copy link

dcsan commented Jul 25, 2020

I'm dump ing an object, and fields without values come out like this:

fieldName: !<tag:yaml.org,2002:js/undefined> ''

how can I suppress that to either undefined or just to skip it like JSON.stringify ?

I tried some options from the safeDump

const blob = yaml.dump(obj, { skipInvalid: true, lineWidth: 200 })

https://github.com/nodeca/js-yaml#safedump-object---options-

but without success. I guess I can strip out the undefined fields, but I'd have to do a deep clean of the whole object... also check for false vs undefined etc. etc.

I tried this but it didn't have any effect:
const clean = { ...obj } // remove nulls?

Sure there must be a nicer way to handle this with js-yaml ?
Do I have to define my own schema?

related:
#456
https://stackoverflow.com/a/38340374/1146785

  async debugMessage(obj) {
    console.log('json', JSON.stringify(obj, null, 2))
    const blob = yaml.dump(obj)
    console.log('yaml', blob)
  }


// json 

{
  "msg": "router",
  "input": "sleep",
  "eventType": "action",
  "handled": {
    "handled": true,
    "doc": {
      "match": "^cont|.*",
      "goto": "prologue"
    },
    "klass": "room",
    "history": [
      "goto"
    ]
  }
}

// yaml 

msg: router
input: sleep
eventType: action
parsed: !<tag:yaml.org,2002:js/undefined> ''
handled:
  handled: true
  doc:
    match: ^cont|.*
    goto: prologue
  klass: room
  history:
    - goto
@dcsan
Copy link
Author

dcsan commented Aug 26, 2020

bump

super annoying. currently I have to do this:

  // strip out elements with undef values for cleaner YAML dumps
  removeEmptyKeys(obj) {
    if (!obj) return {}  // fixme - handle better?
    Object.keys(obj).forEach(key => {
      // if (obj[key] && typeof obj[key] === 'object') Util.removeEmptyKeys(obj[key]);
      if (obj[key] === undefined) delete obj[key];
    });
    return obj;
  },

or the parse results default to full of junk

canTake: false
hidden: !<tag:yaml.org,2002:js/undefined> ''

@aeisenberg
Copy link

I'm having the same problem. Here's my solution, which won't work if you have a circular object or are using any special yaml types:

yaml.safeDump(JSON.parse(JSON.stringify(workflow))

@NelsonFrancisco
Copy link

An option would be a nice addition 👍

@rlidwka
Copy link
Member

rlidwka commented Dec 18, 2020

Fixed in 56d5616 (currently in dev branch).

Now undefined follows roughly the same black magic as in JSON:

  • replaced with null in collections (errors out if null isn't in the schema)
  • removed from mappings entirely if either key or value is undefined

If user defines custom schema for undefined, it serializes as before.

@rlidwka rlidwka closed this as completed Dec 18, 2020
@mk-pmb
Copy link

mk-pmb commented Dec 29, 2020

I'd like an option what do with undefined when it's found in a mapping (dictionary), and another one for how to translate it in lists. I'd like to choose either a string as which to encode it (even the empty string in some exotic cases), or to omit it. The latter could be expressed by setting the option to false. Maybe we could also allow functions, passing them the path (array of steps) we have dived to reach the value, the current original container, and the top level original value? Then the function can dynamically decide a string or false, or throw an error.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants