BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.67k stars 339 forks source link

Uncaught TypeError: Cannot set property 'tmplName' of undefined #310

Closed minias closed 7 years ago

minias commented 7 years ago

Chrome version 57.0.2987.37 beta (64-bit) jsRender v0.9.83 (Beta)

This code produces a very rare error. ..[850 Line] In my opinion, the value of the object is likely to not be declared.. If the object is not defined, it is likely to be resolved by handling the exception.

value.tmplName = name = name || currentName;

image

image

BorisMoore commented 7 years ago

Can you give more information on what you are doing? Are you using JsRender with jQuery or without? How are you declaring your template? Can you show your code where you call $.templates(...)?

minias commented 7 years ago

ok. We're using jquery together. image

The following functions are reproduced and reused as follows : image

Call up the .inject function here. image

Do you need more information?

BorisMoore commented 7 years ago

What kind of element is being used (with id "major-tmpl") to declare the template. It is not a good idea to use elements other than script blocks as containers for registering templates. Otherwise best to use a string. https://www.jsviews.com/#compiletmpl.

If you do use a container element, then JsRender caches the compiled template. If you then re-access the template by a second call to $.templates("#major-tmpl"), the cached version will be used. But in your case it looks as if the cached copy or the container element have been corrupted. For example the following code will simulate the error condition you are hitting:

var tmpl = $.templates("#major-tmpl"); // Compile template

var html = tmpl.render(data); 

$("#major-tmpl").data("jsvTmpl", null); // Remove the cached compile template, to provoke error scenario

var tmpl2 = $.templates("#major-tmpl"); // Try to reaccess and reuse compiled template (Error)

var html2 = tmpl2.render(data); 

Is there anything you are doing which might corrupt or modify the element, or the cached copy of the template?

The following version of JsRender includes a defensive fix for the above scenario. You can test it to see if it successfully resolves your issue. jsrender.zip

minias commented 7 years ago

@BorisMoore I changed the file. So no further errors occur. Thanks for the patch version. 👍

BorisMoore commented 7 years ago

Did you figure out why or how that element, or its JsRender data is getting modified/corrupted? What element type are you using as container for the template? With that patch it may be working, but it means you are recompiling the template every time you use it (or every time the cached copy is lost/corrupted), which is not good for perf...

minias commented 7 years ago

@BorisMoore
In my opinion, existing developers seem to be unfamiliar with the use of jsrender. The problem seems to be reusing the cache in the AJAX, as you have guessed. Even though we should not use the cache intentionally, the previous developers ignored it and applied it to the template. I am currently improving the system we use. Our final goal will be to remove all libraries that prevent real-time elements from our systems. Nevertheless, I am grateful to you for correcting the current issue.

BorisMoore commented 7 years ago

OK - thanks for the update. Closing this issue.