lukeed / obj-str

A tiny (96B) library for serializing Object values to Strings.
MIT License
249 stars 7 forks source link

Using it with Svelte: undefined values #12

Closed minushabens closed 3 years ago

minushabens commented 3 years ago

I'm using obj-str with Svelte.

This is an example: https://svelte.dev/repl/8ed7006e598e48b3a5083bf6c6abe3f4?version=3.35.0.

<script>
    let className
    export { className as class }

    function objstr(obj) {
        var k;
        var cls = ""
        for (k in obj) {
            console.log("k:", k, "v:", obj[k])
            if (obj[k]) {
                cls && (cls += " ")
                cls += k
            }
        }
        return cls
    }

    $: klass = objstr({
        "default": true,
        // [className]: className != null,
        // [className]: !!className,
        // className: className != null,
        [className]: className,
    });
</script>

<div class={klass}>klass: {klass}</div>

QUESTIONS:

  1. Which method is faster between

    1. [className]: className != null and
    2. [className]: !!className ?
  2. As I'm new to javascript I also noticed that these two methods don't work, right?

    1. className: className != null
    2. [className]: className

    They both return className instead of className value, even after the toggle() call, why?

Maybe we can add Svelte instructions to Readme.

minushabens commented 3 years ago
$: klass = objstr({
  "default": true,
  className,
});

would be amazing to write!

lukeed commented 3 years ago

1) These are not the same thing. The className != null case means that false and/or 0 will make the condition true. 2) They'll work, but they're not the same thing either. If you look at the compiled JS output of your REPL, you'll notice that this is actually a Svelte bug. You should report this 👍 3) (Your comment) This is possible, but obj-str relies on key names being added to the generated string value. So, this means that the key name is "className", expanding to { ..., className: className }. This means that so long as className (the variable value) is truthy, then your klass will contain "className" in its string value. This is what's happening with (2) & your REPL link.

What you probably want here is clsx:

<script>
    import cx from 'clsx';

    let className
    export { className as class }

    $: klass = cx('default', className && className);
    // ^ will be "default" and the *value* of `className` when non-empty
</script>

<div class={klass}>klass: {klass}</div>
minushabens commented 3 years ago

Bug opened on sveltejs/svelte.

So, if I'm not wrong, you suggest using [className]: className, right? (as soon as they fix the bug)

lukeed commented 3 years ago

no it should be [className]: !!className