1
votes

My App uses Spring Boot for backend and Angular JS for frontend.

I use Thymeleaf for the multi-language support. Thymeleaf requires all html files to be put under a folder called templates.

At the frontend, I used angular's routeProvider to redirect pages. Here is the code:

angular.
    module("myapp").
    config(function ($routeProvider) {
    $routeProvider
    .when( '/dashboard/:param1/:param2/', {
        templateUrl: 'templates/pages/dashboard.html',
        controller: 'dashboardController',
        reloadOnSearch: false
    })
    .when( '/login/', {
        templateUrl: 'templates/auth/login.html'
    })
    .otherwise({ redirectTo: '/dashboard/global/-1' });
});

At the java side, I have some ViewController code in my WebConfig.java

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        super.addViewControllers(registry);
        registry.addViewController("/login").setViewName("auth/login"); //This works

      registry.addViewController("/dashboard/**").setViewName("page/dashboard"); //Don't work, 404 error
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);      
    }
}

The login pages works, but for dashboard, Angular gives me a 404 error.

GET http://localhost:8080/myapp/templates/pages/dashboard.html 404 (Not Found)

If I move the dashboard out of template folder, and change the templateUrl to

templateUrl: 'pages/dashboard.html', 

Angular now can find and display the dashboard page, but Thymeleaf no longer works since it is out of the template folder. I've lost the multi-language ability.

I see login.html is a complete html page with the head, body; dashboard.html is a part of index.html, so it is just a big div.

I am confused on the Spring MVC and Angular routerProvider. Is possible to use ANGULARJS $routeProvider in my case? Should I only use Spring MVC since I do need Thymeleaf for the multi-language ability? Any suggestions?

1
Wouldn't be more convenient to internationalize your frontend with Angular i18n utilities? I think it is possible. - Jakub Ch.
@JakubCh: Yeah, that's doable. My app needs to support 6 different languages, I would prefer to process template at the backend with Thymeleaf and send only one html files to front end than sending 6 html/javascript files for the front end to decide which one to use. - Half Ass Dev

1 Answers

0
votes

After googling the topic, I found the solution from this post: Angular simple routing is not working

Basically, for Thymeleaf to work, the html template must be put under the templates folder.

For Angular template, if you don't need Thymeleaf to process the template, the html template can be put under the static folder, and in $routeProvider, you provide the template location as this:

templateUrl: 'pages/dashboard.html',  //the template is under static/pages

If you do need Thymeleaf to process the template, you must put the template under templates folder, and and in $routeProvider, you provide the template location as this:

 templateUrl: 'dashboard',  //this is more like a nick name, there is no .html

This tells Angular to get dashboard from backend Thymeleaf. At the java side, we need to add a viewController to expose the thymeleaf template

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        super.addViewControllers(registry);
        registry.addViewController("/login").setViewName("auth/login");//register controllers that will expose template
        registry.addViewController("/dashboard/**").setViewName("pages/dashboard"); //At here, you mapping the nick name and indicate the template is actually located under templates/pages


        //for Angular Directives
        registry.addViewController("/breadcrumb").setViewName("directives/breadcrumb");
        registry.addViewController("/flipcard").setViewName("directives/flipcard");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);      
    }
}

For the template, you can just keep them inside a big div tag, there is no need to add the header and body tag to make it a full html.