Bundling in Web API - angularjs

I trying to bundle my SPA and I just can't get it to work.
My Tech Stack
WebAPI 1.0
AngularJs 1.3.X
I am just using vanilla HTML with Angular Calls to Backend WebAPI controllers. Since I am using vanilla HTML and not MVC views can I even use bundling. Do I need to return the bundled url from a WebAPI Controller?

I see it's been a year since you posted the question, but I found this post that I think answers the question in your problem.
Bundling and minification without ASP.NET MVC
It actually gives instructions on how to enable it.
First you have to check if you have installed the Nuget Package Microsoft.AspNet.Web.Optimization
(Tools -> Nuget Package Manager -> Manage Nuget Packages for Solution)
Create a BundleConfig Class and define your bundles:
using System.Web.Optimization;
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/js").Include(
"~/Scripts/*.js"));
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Styles/*.css"));
}
}
Register the BundleConfig class within the application start in the global.asax:
void Application_Start(object sender, EventArgs e)
{
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Reference the bundles in your HTML document.
Enable bundling by disabling debug mode.

Related

Spring boot + (Thymeleaf is overriding React JS views)

I have created an error page with Thymeleaf and I use it that way because I can send error messages to users through the controller.
#ExceptionHandler(Exception.class)
public ModelAndView controllerExceptionHandler(
Exception e,
HttpServletRequest request) {
ModelAndView mav = new ModelAndView();
String[] messages = e.getMessage().split("</br>");
mav.addObject("message", messages);
mav.addObject("timestamp", new Date());
mav.addObject("url", request.getRequestURL());
mav.addObject("headerMessage", "Error :(");
mav.addObject("contentMessage", "We are working hard to resolve it.");
mav.setViewName("error");
mav.addObject("status", 500);
return mav;
}
In template file I have something like this:
<h1 class="mr-3 pr-3 align-top border-right inline-block align-content-center" th:text="${status}">404</h1>
<div class="inline-block align-middle">
<div>
<h1>Something went wrong...</h1>
</div>
<th:block th:each="msg : ${message}">
<h2 class="font-weight-normal lead" id="desc" th:text="${msg}">The page you requested was not found.</h2>
</th:block>
</div>
Previously I had a simple React JS application also running with Spring Boot and Thymeleaf and then I used Thymeleaf template to show that. I had a template index.html where was actually React JS build file, so every time I had to copy the build file inside there, JS and CSS files into a static folder (after build). Now the React APP got more complex and I decided to use frontendmaven plugin to build it straight away with backend.
How to tell Spring Boot to not try to use Thymeleaf when resolving ReactJS views? This is how I serve ReactJS views.
#RequestMapping("/")
public String index() {
return "index.html";
}
Or would it be possible to get rid of Thymeleaf? Is it possible to send variables to ReactJS views through Java controllers when serving those views? The modelandview example?
How to tell Spring Boot to not try to use Thymeleaf when resolving
React JS views?
Remove ThymeleafViewResolver in webconfiguration and switch to Rest api ( #Restcontroller instead of #Controller ). This way you are telling Spring for not to render a view instead act as api-endpoints.
Now you can update your react code to call these Spring rest apis, prebuilt using maven-frontend-plugin and deploy.
Now the question comes, what is the stating point for your application
Only for this purpose, you can create a single controller which will handle request to "/" and will return index page residing under resources/template folder. This index.html page will be using your prebuilt react pages as -
<script src="built/bundle.js"></script>
Demo application: https://github.com/ankidaemon/Spring5-ReactJS/tree/master/Section5/Video5.3/SpringSecurity-Reactjs-RestAPI
Is it possible to send variables to React JS views through Java
controllers when serving those views
This is called server-side-rendering, however for react this is different then jsp and freemarker, thymeleaf etc and I would say not an easy way to do it with react. You can try your luck with this -> https://codeburst.io/jsx-react-js-java-server-side-rendering-ssr-2018-cf3aaff7969d

Spring-boot: add application to tomcat server

I have a back-end which is build on spring-boot and then some custom code from my school built upon that.
The front-end is pure angular application which I serve from a different server trough a gulp serve.
They're only connected by REST calls.
There's already an authentication module running on the backend and to now I need to serve this angular application from the same tomcat server the back-end is running on so it can also use this authentication module.
I've found this about multiple connectors so I copied it as following class to set up multiple connectors:
#ConfigurationProperties
public class TomcatConfiguration {
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
//tomcat.addAdditionalTomcatConnectors(createSslConnector());
return tomcat;
}
private Connector createSslConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
File keystore = new ClassPathResource("keystore").getFile();
File truststore = new ClassPathResource("keystore").getFile();
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.getAbsolutePath());
protocol.setKeystorePass("changeit");
protocol.setTruststoreFile(truststore.getAbsolutePath());
protocol.setTruststorePass("changeit");
protocol.setKeyAlias("apitester");
return connector;
} catch (IOException ex) {
throw new IllegalStateException("can't access keystore: [" + "keystore"
+ "] or truststore: [" + "keystore" + "]", ex);
}
}
}
Problem is that I don't see or find how I should setup these connectors so they serve from my angularJS build folder.
Upon searching I came upon Spring-Boot : How can I add tomcat connectors to bind to controller but I'm not sure if in that solution I should change my current application or make a parent application for both applications.
My current application main looks like this:
#Configuration
#ComponentScan({"be.ugent.lca","be.ugent.sherpa.configuration"})
#EnableAutoConfiguration
#EnableSpringDataWebSupport
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
If possible I'd like some more info about what connectors are in the spring-boot context.
If this is not the way to go I'd like someone to be able to conform this second solution or suggest a change in my code.
I'm really not sure enough about these solution that I want to go breaking my application over it. (though it's backed up with github)
Just place your AngularJS + other front-end assets into src/main/resources/static folder, Spring Boot will serve them automatically.

CORS issue with Angular Client and ASP.NET Web API

I have a client side application built with AngularJS that is consuming services from a RESTful ASP.NET Web API. So far so good. I have created both of them under the same solution on Visual Studio, the API is an ASP.NET project and the AngularJS is a website. Both projects have to work using windows authorization so I created the API with windows authorization as the default AA mechanism in the project creator wizard, and for the AngularJS I have enable windows authentication on the properties tab of the project.
In order to test the communication between the two applications I decided to build a simple service. I created a Quotation model class, built the controller for it, and then added migrations and added some quotations in the database. I then tried to send a get request from the angular application only to receive this error:
After studying this issue I realized that I had to enable CORS on the web API. So I went to NuGet Package Manager and added the Microsoft.AspNet.Cors package to the project.
I then enabled CORS on the WebApiConfig.cs like this:
namespace Web_API
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.EnableCors();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
And I added the header to my controller class and method (just in case on the class wasn't enough):
namespace Web_API.Controllers
{
[EnableCors("*", "*","*")]
public class QuotationsController : ApiController
{
private Web_APIContext db = new Web_APIContext();
// GET: api/Quotations
[EnableCors("*", "*", "*")]
public IQueryable<Quotation> GetQuotations()
{
return db.Quotations;
}
However, I still get the same error when I make a get request from the AngularJS application. Does anyone know how to fix this issue?
can you please try this:
[EnableCors(origins: "*", headers: "*", methods: "*")]
Also don't use EnableCors in your method. As you've used this on your controller, by default all methods will fall under this rule.
I hope this will solve your problem. Thanks.

IntelliJ - spring boot resources for ES6 configuration

I'm trying to make some simple project with AngularJs using ES6 with Traceur compiler and with Spring Boot as my backend. I already managed to configure my project so it works as I expected. I only have some problems with configuring IntelliJ to see my resources properly.
I put my static resources in src/main/resources/public and configure ResourceHandlerRegistry so that it redirects any unknown request to the main angular application file (I want to use html5 location mode, so it was necessary. I found working configuration in the second answer of this question Spring Boot with AngularJS html5Mode).
The error occurs when I import any of my ES6 modules:
import {appModule as app} from 'resources/app/main.js'; // <- here IntelliJ sees an error, it cannot find such file, but when I run the application it all works as expected
Here I uploaded my whole project: http://www.filedropper.com/spring-boot-test
Could anyone tell me what should I do to get rid of this error in IntelliJ or check what I've done wrong with my project?
btw. I use IntelliJ 14.
Edit:
I had error in StaticResourceConfigurator. It should be:
/* ... */
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/public/");
Instead of:
/* ... */
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/public/**").addResourceLocations("classpath:/resources/");
But it didn't solve my problem.

Durandal, Breeze, and DotNetNuke

I am developing a SPA as a DotNetNuke module. Everything works well, but I can't find a way to make the module work with Breeze. The DNN version i am using is 7.04, which is I think the latest. DNN uses its own WebApi (written on top of WebApi) and the modules have no AppStart folder.
I added this part after some thought
In DNN you can add a route like so:
public class RouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapHttpRoute("MyModuleName", "default", "{controller}/{action}",
new[] { "MyModule.NameSpace" });
//Second route....
//third rout.....
}
}
Breeze on the other hand register the route on AppStart using the WebActivator.PreApplicationStartMethod.
It seems to me that all I need to do is to add a route to the code above and just refer to Breeze as another DNN Module like so
mapRouteManager.MapHttpRoute("BreezeApi,"Breeze", "api/{controller}/{action}...
But according to the comments on breeze's startup class, breeze route should be inserted at the front of ALL api route so I suspect it won't work. Does anybody have any idea?

Resources