linkedin / dustjs

Asynchronous Javascript templating for the browser and server
http://dustjs.com
MIT License
2.91k stars 479 forks source link

Empty string is truthy? #401

Closed shaunlimjin closed 10 years ago

shaunlimjin commented 10 years ago

After upgrading to v2.2.3 from v1.1.1, I've noticed that conditionals that evaluate empty strings now return a "truthy" value.

The following: {?value}{value}{:else}{messages.phone_number_example}{/value}

used to display phone_number_example when value == "", but now prints [Object object] instead.

jimmyhchan commented 10 years ago

cannot reproduce:

Empty strings shows falsy for me.

I'm looking at a simple example using http://linkedin.github.io/dustjs/test/test.html and it is behaving as expected.

Can you provide an example of a template/json pair that is showing the problem?

rragan commented 10 years ago

Ditto. Cannot reproduce with: {?value}true{:else}false{/value}

var json = { value: "" }

This outputs false. Be sure there isn't an extra space between your quotes.

shaunlimjin commented 10 years ago

Sorry for the delayed response. To reproduce:

Template:

{#arguments.phoneNumberModel}{#phoneNumberParts}
        <input type="text" class="text required focused" id="msisdn" name="phoneNumberParts[0].value" value="{?value}{value}{:else}{messages.phone_number_example}{/value}" maxlength="{maxLength}"/>
{/phoneNumberParts}{/arguments.phoneNumberModel}

JSON:

{
    "arguments": {
        "phoneNumberModel": {
            "phoneNumberParts": [
                {
                    "pattern": "[0-9]{10,10}",
                    "maxLength": 10,
                    "minLength": 10,
                    "value": ""
                }
            ]
        }
    },
    "messages": {     
        "phone_number_example": {
            "value": "xxx xxx xxxx",
            "key": "testkey"
        }
    }
}

Output:

<input type="text" class="text required focused" id="msisdn" name="phoneNumberParts[0].value" value="[object Object]" maxlength="10"/>

It works fine if the "messages" object is removed from the json, leaving it like so:

{
    "arguments": {
        "phoneNumberModel": {
            "phoneNumberParts": [
                {
                    "pattern": "[0-9]{10,10}",
                    "maxLength": 10,
                    "minLength": 10,
                    "value": ""
                }
            ]
        }
    }
}

Again, everything was working fine in dust.js v1.1.1

rragan commented 10 years ago

The problem is here: value="{?value}{value}{:else}{messages.phone_number_example}{/value}"

Dust puts params on the context stack via their name so this creates a param that has a function call to evaluate the stuff in the quotes. When the function is evaluated the param name value blocks visibility of the actual data value "value". If you rename the param to "valu", things work as you expect. The order in which things are put on the stack (params) changed but it may change back. That is under discussion. That is why this broke.

Update: Hold that thought. There may be more going on.

Your example still outputs [Object object] because t{messages.phone_number_example} is an object.

shaunlimjin commented 10 years ago

Thanks for the response, Richard.

In my case, the reason why this broke is probably different. My project is also using the dust-helpers library along with version 1.6.3 of the i18next library. My guess there is a compatibility issue with i18next.

The truthy/falsy evaluation is actually working. The [Object object] being printed is actually the messages.phone_number_example object.

Please feel free to close this issue.

Thanks, Shaun