How to use Thymeleaf th:text in reactJS - html

I am running a springboot application with Thymeleaf and reactJS. All the HTML text are read from message.properties by using th:text in the pages, but when I have th:text in reactJS HTML block, reactJS seems angry about it.
render() {
return (
<input type="text" th:text="#{home.welcome}">
)
}
The error is:
Namespace tags are not supported. ReactJSX is not XML.
Is there a walkaround besides using dangerouslySetInnerHTML?
Thank you!

There is no sane workaround.
You are getting this error because Thymeleaf outputs XML, and JSX parsers do not parse XML.
You did this because JSX looks very, very similar to XML. But they are very, very different, and even if you somehow hacked Thymeleaf to strip namespaced attributes and managed to get a component to render, it would be merely a fleeting moment of duct-taped-together, jury-rigged code that will fall apart under further use.
This is a really, really bad idea because JSX is Javascript. You are generating Javascript on the fly. Just to name a few reasons this will not work in the long term:
This makes your components difficult if not impossible to test.
Reasoning about application state will be a nightmare as you will struggle to figure out if the source of a certain state is coming from Thymeleaf or JS.
Your application will completely grind to a halt if Thymeleaf outputs bad JS.
These problems will all get worse with time (Thyme?) as as developers abuse the ease with which they can render server-side data to the client-side, leading to an insane application architecture.
Do not do this. Just use Thymeleaf, or just use React.
Sample Alternative: I primarily work on a React application backed by a Java backend. So I understand how someone could stumble upon this hybrid and think it might be a good idea. You are likely already using Thymeleaf and are trying to figure out how you can avoid rewriting your servlets but still get the power of React.
We were in a similar boat two years ago, except with an aging JSP frontend, but the difference is negligible. What we did (and it works well) is use a JSP page to bootstrap the entire React application. There is now one JSP page that we render to the user. This JSP page outputs JSON into a single <script> tag that contains some initial startup data that we would otherwise have to fetch immediately. This contains resources, properties, and just plain data.
We then output another <script> that points to the location of a compiled JS module containing the entire standalone React application. This application loads the JSON data once when it starts up and then makes backend calls for the rest. In some places, we have to use JSP for these, which is less than ideal but still better than your solution. What we do is have the JSP pages output a single attribute containing JSON. In this way (and with some careful pruning by our XHR library) we get a poor man's data interchange layer built atop a JSP framework we don't have time to change.
It is definitely not ideal, but it works well and we have benefited vastly from the many advantages of React. When we do have issues with this peculiar implementation, they are easy to isolate and resolve.

It is possible wrap ReactJS apps in Thymeleaf. Think if you want a static persistent part (like some links, or even just displayed data), you could use Thymeleaf. If you have a complicated part (something that requires DOM repaints, shared data, updates from UI/Sockets/whatever), you could use React.
If you need to pass state you could use Redux/other methods.
You could have your backend send data via a rest API to the React part and just render your simple parts as fragments or as whole chunks of plain HTML using Thymeleaf.
Remember, Thymeleaf is really just HTML. React is virtual DOM that renders as HTML. It's actually fairly easy to migrate one to the other. So you could write anything "Static" or that does not respond much to UI, in Thymeleaf/HTML. You could also just render those parts in React too, but without State.
Thymeleaf 3 allows you to render variables from your Java to a separate JS file. So that is also an option to pass into JSX
function showCode() {
var code = /*[[${code}]]*/ '12345';
document.getElementById('code').innerHTML = code;
}

Now you can use data- prefix attributes (ex. data-th-text="${message}").
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#support-for-html5-friendly-attribute-and-element-names

Related

Storing content to display on page

In my current application we have a service which responds with a XML.With the XML we do XSLT transformation to a HTML and display it on our web page(review,Tutorials).
My Question here is this the only way to store the content of the webpage and display it as required.
We are going to migrate to a Angular app.So do i still continue using the XSLT way or is there other better way to store the content of the page and display it.
I suggest you use native JSON communication, if possible. Or try to convert your data to a native JSON object - Angular (and javascript, really) can work much better and faster with the native JSON itself.
Although, f you want to display a html content, you can use the innerHTML tag.
If you manage to get the data in a JSON, read more and learn about the angular tehcniques of displaying data. I suggest you do the tutorial on angular.io :)

React with MVC data annotations and unobtrusive validation

We are currently looking to experiment with modern frontend frameworks like react on an MVC4 project. We use data annotations in our models and we have a lot of forms that use unobtrusive validation on the UI.
The main thing is finding a way to use react to generate the content while still being able to make use of features like unobtrusive validation. As I understand it, it really is just a bunch of data-val attributes dynamically generated when using HTML helpers like TextAreaFor, ValidationMessageFor with the attributes getting values from the data annotations in the model classes.
I've tried several things including
ReactDOM.render(
#using (Html.BeginForm("xyz", "xyz", FormMethod.Post))
{
#Html.TextBoxFor(x => x.Email)
which results in the input box not being editable for some reason.
I'd prefer to do something more like
ReactDOM.render(
<form><input type="text" data-val="#Model.datannotations[1].val" /></form>
Is that possible? How does one get the data-val values from the model anyway? What is the best way to achieve this?
it should not be possible.
These are two differents ways to delvelop the ui.
The razor way is preprocessing the markup code in server side to fill it.
And react works in another flow using the lifecycle methods, you should have already loaded the data-anotations values for accessing it on render.
Therefore, to make this works you have to run razor engine first to fill the markup and next using react engine.
I don't recommend use this approach because it's too hard to develop on it and the developers team have to keep that flow in mind while they are developing
Note this
ReactDOM.render(<ComponentMustHaveJSX/>)

Email rendering on AngularJS server

I have an AngularJS 1.x app and a node.js server which needs to send emails occasionally. The emails require that horrible old-style HTML and CSS to make them render nicely in the major email clients, but they also share much data and logic that is already there in the Angular app.
I could use Jade, Pug, Mustache, doT, etc... as an Express templating engine, but it seems to me, ng-repeat, ng-if would also do the job without having to learn another framework and syntax.
What approaches do people recommend for using Angular server side to render emails?
First off, is there a email client rendering problem with custom elements and attributes (eg <div ng-if="..." ... ></div>) that will be left over in the email?
If not...
What I really want is some engine that takes a template with Angular markup as an input, processes it within the context of some Angular controller or component, and produces the finally rendered HTML as an output.
Here's some approaches I'm considering
Use Angular 1.x with jsdom or the like. Something like angular-on-server or ng-node-compile.
Use Angular 2.x. angular2-universal-starter is the closest example I've found, but I can't quickly understand how that works and whether it fits my use case.
NOTE: this is not the usual use case that uses Angular server-side to initial page render faster or for SEO purposes. I have no need, after the email is rendered, to run Angular on the "client side" (you can't even do that in emails).

Spring Localization with html

I have created a spring application with multiple language support, using spring localization/Internationalization and jstl. Now I am going to remove all the jsp and replace it with html. Can make use of spring localization/Internationalization and resource bundles in pure html without jstl? (I am sure there has to be a way.)
You can get rid of JSTL if that's what you are asking for. After all, Spring has its own <sp:message> tag.
However, if you want to get rid of JSP completely and only serve static HTML, I am afraid it can't be done correctly.
That is, you can possibly generate the whole page with JavaScript (i.e. jQuery), but how useful is that?
And you'll be forced to implement some means of Localization for JavaScript anyway. I mean you'll probably need to generate file with translations on-the-fly.
It's do-able, but it would be extremely easy to introduce for example concatenation defects (that won't allow for re-ordering the sentence, that is proper translations).
To summarize this: you probably can do that, but you probably should not.
It is possible..with minimum tweaks..
Dont remove jSP,JSTL etc..
Convert each submit request to ajax..A server doesnt care whether a request is a normal browser submit request or XMLHttpRequest(ajax)..server will use JSP,JSTL to prepare appropriate HTML..u need ajax to render that html string into DOM.
$.ajax(url:'/xyz',
success:function(htmlFromServer){
document.open();
document.write(htmlFromServer);
document.close();
});

Creating a page that updates without reloading

I am debating on what to I should learn to accomplish this. Mainly If I take a bunch of info from a database to load on a page what is the best way to manipulate the page and not have to reload. Is the best thing to use something like XML or is there something else I should use. I know a lot of this uses HTML Dom and XML Dom, but I dont want to start learning one yet that I dont need.
The name of the technique you are looking for is AJAX, which stands for Asynchronous Javascript and XML (although most AJAX these days uses JSON [JavaScript Object Notation] instead of XML).
AJAX requires working knowledge of JS and the DOM. Look at jQuery as a library that makes AJAX and DOM manipulation easy.
How it fits together:
Javascript makes asynchronous requests to your server (without refreshing the page) that return the required data. When the request completes, the JS then inserts that data into the DOM
Using jQuery simplifies this process:
$('#data-container-id').load("my-data.html",{get:"data"})
will fetch "my-data.html?get=data" and put the returned html into a div with the id "data-container-id"