I'm working on a front-end project which I have wired up with angularjs. In the main page I have an ng-view component and the router basically matches partial routes to different template views with different controllers, as such:
/* ... */
myApp.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/pages/01-landing-page.html',
controller: 'firstCtrl'
}).
when('/part2', {
templateUrl: '/pages/02-second-page.html',
controller: 'secondCtrl'
})
/* ... */
When I run the project from the Adobe Brackets editor which comes with a built-in server all files are loaded properly, including the view pages from the 'templateUrl' attributes.
However when I try to serve the files from XAMPP, the routing seems to get messed up.
Suppose I have the project inside the following directory path: '/xampp/htdocs/proj/proj1'
The main page "index.html" is loaded, however when the angular tries to load the "/pages/01-landing-page.html" the http request for that component is
GET myipaddress/pages/01-landing-page.html 404 (Not Found)
instead of
GET myipaddress/proj/proj1/pages/01-landing-page.html
Any idea why angular in this xampp instance seems to ignore the relative path to the project but inside the brackets server it serves everything as it should?
Related
I have have done some research here and in general, but couldnt find a proper way to implement this.
We have and MVC/WebAPI2/AngularJS Web app.
I am trying to achive this goal: being able to put my app anywhere in IIS app folder structure without any code changes. That means, get rid of any IIS Application name in my code.
Here is a simple fragment of ng-route path defined:
.when("/", { templateUrl: "Home/Main", controller: "MainController",
controllerAs: "vm" })
Now, the IIS app is called ReportsWeb (but could be any name)
If I set ReportsWeb app under Default Web Site root:
http://localhost/ReportsWeb/
then everything works fine, and templateUrl page is loaded fine.
But if the app is placed under another IIS App (the one we have here is called RealSuiteApps, which is itself under Default Web Site)
http://localhost/RealSuiteApps/ReportsWeb/
then, the templates are not loaded, since constructed URL for templateUrl is no longer valid:
http://localhost/RealSuiteApps/Home/Main
If I change templateUrl to "/Home/Main", constructed URL is not valid again
http://localhost/Home/Main
If I change templateUrl to "./Home/Main", constructed URL is not valid again
http://localhost/RealSuiteApps/Home/Main
Is it possible to define templateUrl only relative to the latest App name in the IIS hierarchy without hardcoding all these names, so that it will work in any IIS app tree
http://localhost/App1/App2/App3/ReportsWeb/
Thanks!
I use grunt-html2js tool to convert all html templates to Javascript at build time, which uses Angular's template cache.
I've defined my grunt task to overwrite the default module naming to templates/ so that I can reference any template easily:
html2js: {
options: {
rename: function (moduleName) {
return moduleName.replace(/^.*[\/\\]/, 'templates/');
}
},
all: {
src: ['./src/**/*.html', '!./src/index.html'],
dest: 'tmp/templates.js'
}
},
This will create a templates.js file that I can include as a script tag. Then I can access any template like so:
templatUrl: 'templates/my-template-filename.html'
Regardless of where it's path was in the source code.
So, I'm pretty new to AngularJS and I'm trying to use AngularJs ngRoute in my application.
It all works smoothly when I start at the application homepage:
http://localhost:8080/appName/
And when I click on links from this point it works smoothly.
However, when I type a URL that I know exists/works, it gives me a 404 error. If I go to that link by using the application instead of the url it loads fine, even though it has the same url.
Eg. http://localhost:8080/appName/search
will give a 404, even though that is the same url that is the default redirect.
Indeed, the only url that will load by typing in the location is the base URL I mentioned above.
My app.js looks like this:
app.config( ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){
$routeProvider
.when("/search", {
templateUrl: "search.html",
controller: "SearchController"
})
.when("/results", {
templateUrl: "results.html",
controller: "ResultsController"
})
.when("/browse", {
templateUrl: "browse.html",
controller: "BrowseController"
})
.otherwise({redirectTo:"/search"});
//This gets rid of the # on the urls to the templates
$locationProvider.html5Mode(true);
}]);
I am hosting this on a glassfish4 server.
Is there something obvious I am missing/misunderstanding about how ngRoute works? Is there some setting that I am missing?
All help appreciated...
EDIT 1: As #Matthew Green below says, I need to configure the webserver to return the index.html for all pages below
http://localhost:8080/appName
I know I am being completely dense here, but where abouts is this configured? I am hosting the code in a MAVEN Jersey-Quickstart-Webapp.
When you use ngRoute, you are using javascript to handle routing to create a SPA. That means you need to hit a real page that loads your routing for your application to know what page to route to.
For example, your http://localhost:8080/appName/ should be routing to your index.html which would contain the javascript for your routing. With that page loaded it knows how to handle the links you have in your application. However, if you were to go directly to http://localhost:8080/appName/pageName you also need that to load index.html, as it is the one that loads your routing. Once your routing is loaded it should direct you to the correct page in your application. Without redirecting in place, http://localhost:8080/appName/pageName is not a real page and therefore correctly returns a 404.
Knowing this, the thing you have to figure out is what kind of server setup you have to configure the appropriate redirects for everything under http://localhost:8080/appName/ to go to your index.html page.
I'm using SPA technique using AngularJS in ASP.NET MVC framework,AngularJS routing between pages are working fine when it's run from VS2013,but after hosting the application in to IIS8.5 routing not working.
When i run the app using IIS express the url was http://localhost:12345/#/home
After publishing http://localhost/myapp/#/home
Here is my app.js,
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/app/views/home.html"
});
In index.html
<li> Home</li>
When i publish my app in windows azure, app is working fine. Because the url was myapp.azurewebsite.net. myapp.azurewebsite.net/#/home
How can i host similarly in local IIS.
You almost find find the answer -- that is all about absolute file path.
Quick fix:
Change templateUrl: "/app/views/home.html" to templateUrl: "app/views/home.html" (remove the heading slash)
Answer:
If you specify the templateUrl as /app/views/home.html, which starts with /, you tell the browser to get it from root.
If your webapp is stored in http://localhost/myapp/, your browser will visit http://localhost/app/views/home.html to get the template.
That also explains why your app works fine when it is places in root directory, but not working in sub directories, like http://localhost/myapp/#/home .
Do not worry about the side effect of relative path. All the resources are calculated relative to index.html.
I have an MVC app that uses AngularJS. I am in the process of organizing the folder structure to be feature based rather than type based.
An example folder structure is now
App (Folder within main project, at same level as Views)
Assets
CSS
JS
Pages
Home
home.js
home.tests.js
home.html
About (etc)
Now the problem is that when ui-router tries to load home.html the web server throws a 400 error. If I go to the file manually in the browser it works. What is the problem here? Why can I not serve files up from this directory. Note that I actually right click the 400 message in the console and choose open in new tab. So I know the file I am looking at is the URL being requested from AngularJS
Here is my ui-router setup
.state('home', {
url: '/home',
templateUrl: '/app/pages/home/home.html',
controller: 'mainPageController'
})
Note:
I serve up a .js file from the same directory which seems to work fine!
I had the exact same problem and it was caused by another developer trying to fix an IE caching bug.
I found the solution here by Ben Cull: https://stackoverflow.com/a/30014936/710268.
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
//disable IE ajax request caching
$httpProvider.defaults.headers.get["If-Modified-Since"] = "Fri, 01 Jan 2010 00:00:00 GMT";
My problem was that the "If-Modified-Since" header was set to '0' and for some reason that was causing html template files to not load.
By default the router is going to start at the top level of your MVC project (i.e. where your Views and App folder sit) and not the folder where your JavaScript is served from.
So in Angular your templateUrl needs to be App/Pages/Home/home.html.
So in your angular router configuration have the property:
templateUrl: 'App/Pages/Home/home.html'
I have a website that will likely be placed within a directory in IIS. When I am running the application on my computer through IISExpress, the routes are relative to the base URL, so I can just define my routes as follows:
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/app/layout/myView.html"
});
This gives me the following URL:
http://localhost:60847/#/home
When I put publish this site to our server, I have the URL:
http://dev.mysite.com/MyApp/#/home
However, I keep getting an error "Failed to load template: /app/layout/myView.html". When I look at Fiddler, I can see that it is trying to pull in the template from http://dev.mysite.com/app/layout/myView.html instead of from http://dev.mysite.com/MyApp/app/layout/myView.html. I have tried rewriting the templateUrl as ../app/layout/myView.html, as ~/app/layout/myView.html, and as ../../app/layout/myView.html. No matter what I do, I still end up trying to pull it from the parent folder instead of from MyApp. I have also tried setting a web.config setting and using that to put a prefix on the templateUrl, but it doesn't seem to want to run that code prior to loading the template. Finally, I have tried setting up a function for the templateUrl, but the way I have that stored in the web.config file creates timing issues with pulling the information.
It seems as if this must be a common issue that I am making overly complicated. Is there a way to make this a relative URL?
You should add to your HTML's head:
<base href="MyApp/" />
See this documentation page for more details.