Giter Site home page Giter Site logo

Comments (20)

BorisMoore avatar BorisMoore commented on June 7, 2024

Yes, thanks, I was aware of this issue, and will fix it soon...

from jsrender.

 avatar commented on June 7, 2024

I have same problem any luck with this issue?
Right now I can only use the code like: {{=$itemNumber-1 undef 0}}

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

I'm planning to include a fix for this, but it may have to wait until some bigger changes that are in the pipeline, since it relates to other issues like #7 - and to make both that issue and this one satisfied has to be compatible with maintaining current perf optimization. If you have a workaround, then best to stay with that in the meantime...

from jsrender.

davepar avatar davepar commented on June 7, 2024

+1, but workaround does work

from jsrender.

Arakade avatar Arakade commented on June 7, 2024

+1 but couldn't get workaround to work with an encoder (new workaround using a function below).

Pre-workaround, I started with {{=shopping.change.amount!currency}} where "currency" is a custom formatter (encoder) registered with...

  $.views.encoders["currency"] = function currency(number) {
    //alert("typeof "+ number +": "+ typeof number);
    try {
      return number.toFixed(2);
    } catch(e) {
      // supplied something other than a number
      return number +"(NaN)";
    }
  }

... so my unformatted workaround became {{=shopping.change.amount undef 0}} which works but has no formatting.
I then tried adding the encoder as {{=shopping.change.amount undef 0!currency}} but it gave same results as no workaround (value if non-zero; else blank).

I then went and read the source but can't adequately-grok-in-sensible-time how to use a formatter with the workaround (thattmpl + compile code is kind'a heavy! :-O ). Guessing didn't work either ;-)

In case it's relevant, I'm using this with JQuery loaded.

Alternative workaround (that allows formatting)

Instead, I switched to using a function...

  $.views.registerHelpers({
    currency: function(number) {
      // alert("typeof "+ number +": "+ typeof number);
      try {
        return number.toFixed(2);
      } catch(e) {
        // supplied something other than a number
        return number +"(NaN)";
      }
    }
  });

... and my template obviously now has {{=$ctx.currency(shopping.change.amount)}}.
Zero and all other values render correctly. HTH other zero formatters!

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

Doing
$.template("Quantity: {{=quantity}}")
generates ... result = "" + "Quantity: " + html($data.quantity || "");
where it should be ... result = "" + "Quantity: " + html($data.quantity);
and $.views.encoders.html should become:

function (text) { 
   if (null == text) return ""; // skip null and undefined elements.
   return String(text).replace(htmlSpecialChar, replacerForHtml); 
}

PS:
(null == text) is true for undefined and null elements, but false for 0 and false,
whereas (text || "") will evaluate to "" for null, undefined, false, and 0.

Another inline optimization possibility is (null == text ? "" : text) instead of (text || "")
which should have good performance and certainly shorter than
("undefined" === typeof text || null === text ? "" : text).

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

Looks like this problem comes from the paramsOrEmptyString optimization.

I have branch (https://github.com/josher19/jsviews/blob/master/jsrender.js) with a commit (josher19/jsviews@338755b) which gets rid of the optimization and puts a similar one in the html encoder. HTML encoded text using {{= item }} will return blank ('') for undefined or null values but not for 0 or false, but using the ! will show 'undefined' and 'null' values:
{{= item !}}

Example usage:


$.template("HTML", "
Qty: {{=Qty}}, null:{{=nil}}, notset:{{=blank}}, bool:{{=bool}}
")(falsy={"Qty":0,"nil":null,"bool":false}) // Expected output:
Qty: 0, null:, notset:, bool:false
// Old output:
Qty:, null:, undefined:, bool:
$.template("NONE", "
Qty: {{=Qty!}}, null:{{=nil!}}, notset:{{=blank!}}, bool:{{=bool!}}
")(falsy={"Qty":0,"nil":null,"bool":false}) // Expected output:
Qty: 0, null:null, notset:undefined, bool:false
// Old output:
Qty:, null:, notset:, bool:

from jsrender.

patridge avatar patridge commented on June 7, 2024

Seeing this open for a year doesn't give me hope I could offer a fix myself, so I hate to simply post a breaking example in both the current jsrender and @josher19's version. I'm still going to take a look at the jsrender source when I get the chance, but there is definitely still an issue when $data is 0. Here's the gist of the example:

<ul id="results"></ul>
<script id="x" type="text/x-jquery-tmpl">
    <li>{{=$data!}}</li>
</script>
<script type='text/javascript'>
    $("#results").html($("#x").render([0, 1, 0, 2, 0]));
</script>

Results in: "<ul id="results"><li>1</li><li>2</li></ul>"

It doesn't even appear to attempt to step into the template to render the zero-value elements of that array. This seems to make workarounds like the custom tag, custom encoder, and helper function ideas fail too.

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

! do have a fix for this already, but it is part of a major update which I have not committed because it involves some breaking changes. I don't want to do breaking changes piecemeal - but rather in one significant upgrade which will require some porting to the new syntax. After that I hope to keep things pretty stable. The JsRender update is ready, but it also ripples to some changes in JsViews, and I am working hard now to integrate JsViews changess with this update too.

So apologies that this is taking some time, but I think/hope the update will be worth the wait! It should be committed in a couple weeks time... I am targetting Beta for JsRender end of February...

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

@patridge : fixed in my fork of the code so now your results render correctly with 0's included in the output.

Technical details: changed render to do

content = null != dataItem ? tmpl( dataItem, new View( context, path, arrayView, dataItem, tmpl, this )) : "";

instead of

content = dataItem ? tmpl( dataItem, new View( context, path, arrayView, dataItem, tmpl, this )) : "";

so now it will render the template for each line unless that line is null or undefined
(before it would skip rendering if the dataItem was falsy, meaning 0, false, "", null, or undefined).

Thanks for posting the example. It indirectly makes a strong argument for TDD.

@BorisMoore: feel free to pull these small changes and merge them with your changes to see if it fixes or breaks anything. Also let me know if you would like help setting up a test suite for new JsRender beta.

PS: Now 0 and false will show up whether or not you use ! when rendering:

$.template('qq', 'Quantity: {{=quantity!}}, Boolean: {{=bool!}}')({quantity:0, bool:false})
// "Quantity: 0, Boolean: false"

$.template('qq', 'Quantity: {{=quantity}}, Boolean: {{=bool}}')({quantity:0, bool:false})
// "Quantity: 0, Boolean: false"

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

I forked your " breaking example" JsFiddle and added a couple more tests.

Red (failing):
http://jsfiddle.net/yUfyH/1/

Green (passing):
http://jsfiddle.net/mW7Fs/

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

Hi Boris,

Updated the original example to use your new code:

<ul id="results"></ul>
<script id="x" type="text/x-jquery-tmpl">
    <li>{{: #data }}</li>
</script>
/*global $ */
$(function() {
    "use strict";
    $("#results").html($("#x").render([-1, 0, 1, 2, 3, 4,
                                  '-- booleans --',
                                  false, true,
                                  '-- null & undefined --',
                                  null, undefined,
                                  '-- strings --',
                                  "", "string"]));
});

Now get '[object Object]' for the "falsy" values of 0, "", null, undefined, and false.

http://jsfiddle.net/Vaxd6/1/

Cheers,
->> Josh <<-

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

Ah, I see. Yes that is a slightly different case than the one I was looking at. I was thinking of the case where you have a data object with a property whose value is 0, or undefined. (e.g. { quantity: 0 } as above) - but this additional scenario is valid too. I have a fix for it, which I'll upload soon...

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

Fixed in 5d284cb.
Closing, but please reopen if the fix does not work for you... Thanks...

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

Yes, that seems to work pretty well:

Now undefined is replaced with "" (a blank string) and null is replaced with the String "null", while 0 and false remain unchanged.

http://jsfiddle.net/Vaxd6/2/

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

Yes, that's the intention. Actually, undefined, 0, null, true and false are rendered by the strings "", "0", "null", "true", "false". Would you expect anything different from this design?

JsRender always renders a string, of course. The return value from render() can never be other than a string.

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

No, I think "" for undefined and "null" for null works well -- issue closed!

You might include in the documentation how to change that back to the old way (delete "falsy" values) or how to change "null" to "" using a helper function.

from jsrender.

BorisMoore avatar BorisMoore commented on June 7, 2024

There has been a new issue submitted suggesting null should render as "".
#87
I think it does make more sense. Any disagreement?

from jsrender.

josher19 avatar josher19 commented on June 7, 2024

I agree. Might include in the docs how to customize what is displayed using helper functions, because displaying "null" can be useful for debugging, but not so useful for displaying in final HTML produced by render.

from jsrender.

patridge avatar patridge commented on June 7, 2024

This definitely fixed that sample jsFiddle (once I updated the syntax: original). I would think an empty string for null/undefined ought to be just fine. I have only had one use-case where I wanted to display "null" for null values and that was an oddball usage. I put together the start of a simple demo using a helper function to display such values for anyone else that runs into a need to do so; it's not elegant, but it should be easily tweaked for someone's debugging needs.

from jsrender.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.