Is it possible to develop an Angular.js application in a way that would be abstracted from the the web directory path in which it will be deployed?
I am trying to put an Angular.js app in a web server subdirectory http://example.com/myproject/, but the router redirects me to the web server root -- http://example.com.
Below is my Angular.js app:
var myproject = angular.module('myproject', []);
myproject.config(function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {templateUrl: 'partials/index.html', controller: IndexCtrl}).
otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
});
function IndexCtrl($scope, $location) {
}
Try setting a <base href="/sudirectory"/> in your <head></head>. That's what I needed to do to get mine working, IIRC
Word of caution: This will mess with any anchor tags that have href="#", as well as act as the root for image srcs and the like.
Related
I have
<base href="/!#/">
at the top of my index.html file. When I go to URL http://localhost:5000/ everything works fine, it instantly add #!/ so the URL is http://localhost:5000/#!/ and page display as expected.
At the server side I have following code which should allow me to use my files
app.use(express.static(path.join(__dirname, 'public')));
Structure of my files is something like:
bookApp(folder)
server.js
public(folder)
index.html
app.js(ngRoute)
views(folder)
css(folder)
controllers(folder)
and my AngularJS routing is:
(function () {
'use strict';
angular
.module('app', [
'ngRoute'
])
.config(config);
function config ($routeProvider) {
$routeProvider
.when('/', {
controller: 'PostsCtrl',
templateUrl: 'views/posts.html'
})
.when('/register', {
controller: 'registerCtrl',
templateUrl: 'views/register.html'
})
.when('/login', {
controller: 'loginCtrl',
templateUrl: 'views/login.html'
})
.otherwise('/');
}
})();
The very first page (views/posts.html) load as expected but when I click
<li>Sign in</li>
the URL is http://localhost:5000/login not as like I thought http://localhost:5000/!#/login.
and it display:
Cannot GET /login
when I manually change URL to http://localhost:5000/#!/login it works fine.
How to fix this behavior?
The only solution I see is to get rid of <base> tag and in every link manually in href directive add !# before slash.
It looks like you are forgetting the ng-view directive: <div ng-view></div> which is the container for the content that is provided by your routing. Place this above your script if you have everything contained in one file.
You can also try:
<ng-view></ng-view>
<div class="ng-view"></div>
Is there any particular reason you are still using Angular 1? I know this isn't technically answering your question, but I would highly recommend that you start using the latest Angular. You can still keep legacy code but it will make a lot of what you are doing a lot cleaner and clear.
I am following a book called MEAN Machine. The code from the part in this book in question can be found at this Github Repo.
When clicking the links in /public/views/index.html which should be routed, I get file not found errors in the web browser.
The code (/public/js/app.routes.js) that does not seem to work:
// inject ngRoute for all our routing needs
angular.module('routerRoutes', ['ngRoute'])
// configure our routes
.config(function($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'views/pages/home.html',
controller : 'homeController',
controllerAs: 'home'
})
// route for the about page
.when('/about', {
templateUrl : 'views/pages/about.html',
controller : 'aboutController',
controllerAs: 'about'
})
// route for the contact page
.when('/contact', {
templateUrl : 'views/pages/contact.html',
controller : 'contactController',
controllerAs: 'contact'
});
$locationProvider.html5Mode(true);
});
In the index.html file, we are pointing to the correct files:
<script src="js/app.routes.js"></script>
<script src="js/app.js"></script>
To test their code, I changed the base tag in index.html to my folder's path which eliminated errors of not finding the above files.
Is this material dated? Also, I realize this book is not using Angular 2. Does Angular 2 vary drastically in routing and is this material deprecated?
Simply run command
node server.js
from '12-angular-routing' directory and open in browser http://localhost:8080
The problem is that browsers by default does not allow AJAX requests to files located on your local file system. In this case you should run your local server which serves client application(server.js is simple express server).
In tutorial
When you now navigate to /index.html, you are redirected to
/index.html#!/phones and the phone list appears in the browser.
Where is it configured, to redirect /index.html to /index.html#!/phones ?
if you continue reading the tutorial you will find this section Configuring a Module and here the tutorial talks about ngRoute and hte config file app/app.config.js.
In this file you configure your routes, so with this:
angular.
module('phonecatApp').
config(['$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider.
when('/phones', {
template: '<phone-list></phone-list>'
}).
when('/phones/:phoneId', {
template: '<phone-detail></phone-detail>'
}).
otherwise('/phones');
}
]);
You can see that no one state has the / path so it will apply these sentence otherwise('/phones') and it will redirect to that url.
Keep in mind that if there is no one match it will go to otherwise.
If you look at App Config
$routeProvider.
when('/phones', {
template: '<phone-list></phone-list>'
}).
when('/phones/:phoneId', {
template: '<phone-detail></phone-detail>'
}).
otherwise('/phones');
}
In this case case when you go to '/' no mapping is configured ,so it goes to otherwise('/phones');
you have to find function responsible for routing. Look at app.config.js file.
Suggestion: In bigger applications good practise is separating routing for each module in single file.
I have installed my Angular App in a location like this:
http://example.com/my-app
My App routing is like this:
var myApp = angular.module('myApp', ['ngRoute','ngAnimate', 'ui.bootstrap', 'angularFileUpload']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/templates', {
controller: 'TemplatesController',
templateUrl: '/components/com_myApp/myApp/views/templates/template-list.html'
})
.when('/apps', {
controller: 'AppController',
templateUrl: '/components/com_myApp/myApp/views/apps/app-list.html'
})
.otherwise({
redirectTo: '/templates'
});
}]);
Now what happens is, when I go to http://example.com/my-app, the url instead of showing http://example.com/my-app#/templates it is showing as http://example.com/templates
It seems the otherwise condition is basically removing the base directory my-app# from the url. I have been scratching my head over this and after reading I also tried adding base url to head tag and tried changing the myApp.config to this:
myApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
....
}
But although the routing seems to work when using $locationProvider like the above, the base url is still not showing the way I want it. The url is showing like this http://example.com/templates without my-app in the url path. I dont want Angular to remove the base path from the URL and I want the urls to show like this http://example.com/my-app/..xyz...
Why is Angular doing this?
This is happening because you've instructed Angular to not use hashbang URLs by specifying $locationProvider.html5Mode(true). Remove or otherwise comment out that code snippet and if you specified <base href="/"> in your root template file, remove or comment out that also and just use ngRoute without those.
In my Angular app, I'm trying to render partials that load into the index page when a user clicks a link. It worked fine before with the following code:
//app.js in Angular
angular.module('myApp', [
'ngSanitize',
'ngRoute',
...
]).
config(['$routeProvider', '$locationProvider', '$sceDelegateProvider', function($routeProvider, $locationProvider, $sceDelegateProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MainController'});
$routeProvider.when('/File/:fileID', {templateUrl: 'partials/currentFile.html', controller: 'FileController', controllerAs: 'file'});
$routeProvider.otherwise({redirectTo: '/view1'});
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'https://www.url.com/**']);
$locationProvider.html5Mode(true);
}]);
But when I add Express, it doesn't work:
var express = require("express");
var logfmt = require("logfmt");
var app = express();
app.use(logfmt.requestLogger());
app.use(express.static(__dirname + '/app'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.get('*', function(req, res) {
res.sendfile('./app/index.html');
});
This works fine if I just want to display the index page. When I add the following code though, it displays the plain HTML (of the partial), but without the CSS or Javascript.
app.get('/partials/currentFile.html', function(req, res) {
res.render('./app/partials/currentFile.html');
});
How do I go about rendering a partial with Express in a way that works with Angular?
I've tried looking at the Express api for get(), render and sendfile, but they weren't that helpful in my situation. Other users have asked a similar question on here before, but they usually involve another file that Express routes to and I'm wondering if I can do it without adding any extra files since it's already an issue with adding just a file to include Express.
The currentFile.html doesn't load any CSS or Javascript itself. Before I added Express, it was a partial that was loaded in index.html, which loaded all the extras.
Any help is appreciated. Thank you
I didn't fix the problem directly, but I worked around it. The problem was that I wanted to render a partial onto the index page. The overarching goal of the app is a single-page application, so in the end, it's just one page that matters.
It would have been nice to have different partials to render for testing, but alas nobody seems to know either what I'm asking or I'm complicating the issue. Either way, I've found a way around it by just getting rid of all the other partials and just redirecting all URL requests to the single page app.
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MainVideoController'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.when('/file', {templateUrl: 'partials/currentFile.html', controller: 'FileController', controllerAs: 'file'});
$routeProvider.otherwise({redirectTo: '/file'});
...
Note that the partials view1 and view2 DO NOT work when trying to visit domain.com/view1 or /view2.