2

I'm trying to create the simplest spring-boot with reactJS project. I had the back-end working (the postgres connection and /api route working). I created the project with spring initializer and included thymeleaf at that time, based on the tutorials I was following. But then when I started adding ReactJS I got a SAXParser error. Googling this resulted in several resources telling me that reactJS and Thymeleaf don't work well together. I'm not familiar with either. I tried removing Thymeleaf from the dependencies in gradle, but it is somehow still being pulled in.

The tutorial I'm following is : https://stormpath.com/blog/crud-application-react-spring-boot-user-authentication

The error I get is :

org.xml.sax.SAXParseException: Open quote is expected for attribute "employee3" associated with an element type "Employee".

I added the employee1, employee2, etc. in different parts to try to help me find the area where the error was happening. Before that there were multiple things just named 'employee' so I had no idea where the error was.

Here is index.html:

<!DOCTYPE html>
<html>
<head>
    <title>React + Spring</title>
</head>
<body>
<div id='root'></div>

<script src="link-to-fb.me.stack.overflow.doesn't.like/fb.me/react-15.0.1.js"></script>
<script src="link-to-fb.me.stack.overflow.doesn't.like//react-dom-15.0.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

<script type="text/babel">
var Employee = React.createClass({
  render: function() {
    return (
      <tr>
        <td>{this.props.employee1.name}</td>
        <td>{this.props.employee1.age}</td>
        <td>{this.props.employee1.years}</td>
      </tr>);
  }
});
var EmployeeTable = React.createClass({
  render: function() {
    var rows = [];
    this.props.employees.forEach(function(employee2) {
      rows.push(<Employee employee3={employee2} />);
    });
    return (
      <table>
        <thead>
          <tr>
            <th>Name</th><th>Age</th><th>Years</th>
          </tr>
        </thead>
        <tbody>{rows}</tbody>
      </table>);
  }
});

var EMPLOYEES = [
  {name: 'Joe Biden', age: 45, years: 5},
  {name: 'President Obama', age: 54, years: 8},
  {name: 'Crystal Mac', age: 34, years: 12},
  {name: 'James Henry', age: 33, years: 2}
];

ReactDOM.render(
  <EmployeeTable employees={EMPLOYEES}/>, document.getElementById('root')
);
</script>
</body>
</html>

Also, and this may be a separate question, what is the proper directory structure for a spring-boot project with ReactJS? And if I remove thymeleaf, will I have to change my directory structure? Currently it is this:

/src
  /main
    /java
    /js
      app.js
    /resources
      /static
      /templates
        index.html
      application.properties

and the Controller is

@Controller
public class HomeController {

    @RequestMapping(value = "/")
    public String index() {
        return "index";
    }

}

So that localhost:8080 resolves to the index.html.

Here's my gradle file :

buildscript {
    ext {
        springBootVersion = '1.5.8.RELEASE'
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

group = 'com'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile("org.springframework.boot:spring-boot-devtools")
    runtime('org.postgresql:postgresql')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}
user26270
  • 6,904
  • 13
  • 62
  • 94
  • Can you show index.html? Are you adding js code inside some ` – varren Nov 03 '17 at 05:44
  • 1
    Why don't you create a standalone react project and then get the data needed from the Spring project? – juanlumn Nov 03 '17 at 08:57
  • @varren I've added index.html, but I'm probably going to go the route of a separate react project. Thanks – user26270 Nov 04 '17 at 14:22
  • @user26270 sure, or you can put your index.html in `static/` and resolve it without thymeleaf help, just as static resource. Should work just fine if you don't need dynamic data and can get everything you need from some rest endpoint – varren Nov 04 '17 at 14:29
  • @varren; thanks again; also, what do you mean by dynamic data? – user26270 Nov 04 '17 at 14:31
  • also, does thymeleaf only work on files in templates folder? – user26270 Nov 04 '17 at 14:32
  • @varren I moved index.html to /static, but now localhost:8080 doesn't resolve to that. I mean, with index.html in /static, when I go to localhost:8080, I get another Thymeleaf error : org.thymeleaf.exceptions.TemplateInputException: Error resolving template "index", template might not exist or might not be accessible by any of the configured Template Resolvers – user26270 Nov 04 '17 at 14:35
  • @user26270 actually after looking at your index.html i think that you just need to put js related to react in a separate .js file. include this file in index.html and this will solve it for you... Or if you use thymeleaf 3, can use custom inline js tag attribute http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining ` – varren Nov 04 '17 at 15:17
  • @user26270 And about serving static, you will have to setup https://stackoverflow.com/questions/21123437/how-do-i-use-spring-boot-to-serve-static-content-located-in-dropbox-folder but you probably don't need it. And by dynamic data i mean that you have some data in db, that spring can serve and instead of `var EMPLOYEES = [{...},{...},{...}]` you are going to make one more get request to the server. Or with thymleaf you could inline some variables from spring controller to js like described in docs http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#javascript-inlining – varren Nov 04 '17 at 15:25

0 Answers0