I am working on an AngularJS project. I removed # from the URL using and $locationProvider.html5mode().
Depending upon environment, I want the href attribute for base tag to be dynamically updated from a config file. I created an env.js that contains simple configurations.
env.js
(function (window) {
window.__env = window.__env || {};
window.__env.baseUrl = '/';
window.__env.enableDebug = true;
}(this));
I used this env file in my app.js and inside app.run() updated $rootScope.baseurl to baseUrl in env.js. It is working fine inside console.log() but not in my index.html. I am getting the uncompiled code i.e {{ $rootScope.baseurl }}
app.js
import controllers from './controllers';
var env = {};
if (window) {
Object.assign(env, window.__env);
}
var app = angular.module('myapp', ['ui.router', controllers]);
app.constant('__env', env);
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider.state("home", {
url: "/",
templateUrl: "app/components/home/home.view.html",
controller: "HomeController"
}).state("login", {
url: "/login",
templateUrl: "app/components/login/login.view.html",
controller: "LoginController"
});
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
});
app.run(function($rootScope, __env){
$rootScope.baseurl = __env.baseUrl;
console.log($rootScope.baseurl);
});
Index.html
<html ng-app="myapp">
<head>
<title>MYAPP</title>
<base href="{{ baseurl }}">
</head>
<body>
<div ui-view>
</div>
</body>
<script type="text/javascript" src="public/lib/js/angular.min.js"></script>
<script type="text/javascript" src="public/lib/js/angular-ui-router.min.js"></script>
<script type="text/javascript" src="env.js"></script>
<script type="text/javascript" src="public/app.js"></script>
</html>
Please help me out . Thanks
You can't use angular to set it since it needs to be set before any requests are made for page resources like scripts, stylesheets, images etc since you are using relative paths
You could try replacing the <base> with something like:
<script type="text/javascript" src="env.js"></script>
<script>
document.write('<base href="' + window.__env.baseUrl + '" />');
</script>
Or
<script type="text/javascript" src="env.js"></script>
<base id="base">
<script>
document.getElementById('base').href = window.__env.baseUrl;
</script>
Related
Sorry for the possible repost, but I don't know how else to write this. I've been using this website to create a small angularJS webpage using nodeJS as well, and I've gotten to the part of separating the angular code from the view, or HTML. What I've found was that when I tried to separate them nothing worked any more.
Here's my code so far:
Home.html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<!-- <script>
var myApp = angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
</script> -->
</head>
<body>
<!-- <script>
myApp.directive('myDirective', function() {
return {
template: "This is a test directive."
};
})
</script> -->
<h2>myApp Test</h2>
<div ng-app="myApp" ng-controller="myCtrl" ng-init="quantity = 10; cost = 5">
<p>Color: <input type="text" style="background-color:{{myColor}}" ng-model="myColor" value="{{myColor}}"></p>
<p>Total in dollar (raw exp): {{quantity * cost}}</p>
<p>Total in dollar (span): <span ng-bind="quantity * cost"></span></p>
<p> First Name: <input type="text" ng-model="firstName"></p>
<p> Last Name: <input type="text" ng-model="lastName"></p>
<h1>Hello, {{firstName + " " + lastName}}</h1>
</div>
Are you even changing?!
</body>
<script type="javascript" src="../JS/myApp.js"></script>
<!-- <script type="javascript" src="../JS/myApp.module.js"></script> -->
<script type="javascript" src="../JS/myCtrl.js"></script>
<!-- <script type="javascript" src="../JS/myCtrl.component.js"></script> -->
</html>
myApp.js / myApp.module.js:
var myApp = angular.module('myApp', []);
myCtrl.js / myCtrl.component.js:
myApp.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myColor = "red";
});
// app.directive('myDirective', function() {
// return {
// template: '<p><h3>This is a test directive.<h3></p>'
// };
// });
Finally, here's my folder hierarchy:
If what I've done wrong is already evident, there's no need for you to continue reading.
Now the commented-out code is important as well. These are both the other things I've tried, and what I wanted to implement. I have tried:
Re-adding all the angular code back to the head tag to make sure it was still working at all. It worked, aside from the directive stuff (which, at point, I believe would have to be part of a separate module, but not the point, nonetheless).
Moving the script references, which are, and were, located below the body, to the head.
Moving the script references to the top of the body.
Moving everything into just *one* file (myApp.module.js).
Renaming both "myCtrl.component.js" and "myApp.module.js" to "myCtrl.js" and "myApp.js", respectively, to ensure possibly-antiquated angularJS nomenclature wasn't an attribution.
Adding "type="javascript"" to the script references.
"Hard refreshing" to make sure old documents weren't cached.
Tested to see if it was even requesting the files from the server using node. It doesn't look like it is.
If you need the nodeJS part of it, it's here as well (index.js):
var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var myUrl = url.parse(req.url);
var basename = path.basename(myUrl.path);
console.log('request url: ' + req.url);
console.log('url path: ' + myUrl.path);
console.log('basename: ' + basename);
fs.readFile('../HTML/Home.html', function(err, data) {
res.writeHead(200, { 'ContentType': 'text/html' });
res.write(data);
res.end();
});
}).listen(8080);
The problem is in your script tag
<script type="javascript" src="../JS/myCtrl.js"></script>
It should not be
type="javascript"
Either change it to
type="text/javascript"
or remove the type totally. Due to incorrect type , it is not loading controller and other js files to browser.
I'm trying to get route parsing for $routeProvider to generate .when()'s from array. Here is the code in app.js that I've tried. This generates correct routes, but causes infinite loops of "Tried to load AngularJS more than once". I only load angularjs in the index. html file, into which the view is rendered. How can I get routes from array to work? Array structure is "route":"fileName.html".
var dynape = angular.module("dynape",['ngRoute','dynape.controllers','dynape.services','ngCookies']);
dynape.config(['$routeProvider','$locationProvider',
function($routeProvider,$locationProvider) {
var db = new PouchDB('http://localhost:5984/siteconf', {skipSetup: true});
db.get("pages").then(function(doc) {
var tmp = doc;
delete tmp["_id"];
delete tmp["_rev"];
delete tmp["/"];
for(p in tmp) {
console.log(p.toString());
$routeProvider.when(p.toString(), {
controller: "SiteController",
templateUrl: "views/pages/"+tmp[p]
});
}
});
// Follwing routes never change
$routeProvider.when("/",{
controller: 'SiteController',
templateUrl: "views/frontPage.html"
}).when("/admin",{
controller: 'AdminLoginController',
templateUrl: "views/admin/login.html"
}).when("/admin/setup", {
controller: 'SetupController',
templateUrl: "views/admin/setup.html"
}).when("/admin/dashboard", {
controller: 'AdminActionController',
templateUrl: "views/admin/dashboard.html"
}).when("/admin/pages", {
controller: 'AdminActionController',
templateUrl: "views/admin/pages.html"
}).otherwise({
redirectTo: "/"
});
$locationProvider.html5Mode(true);
}
]);
angular.module("dynape.controllers",[]);
angular.module("dynape.services",[]);
The index.html into which I render the view:
<!DOCTYPE html>
<html ng-app="dynape">
<head>
<base href="/">
<meta charset="utf-8">
<title>A Dynape Site</title>
<link rel="stylesheet" href="/css/base.css" media="screen">
<link rel="stylesheet" href="/css/components-base.css" media="screen">
<link rel="stylesheet" href="/css/gridsys.css" media="screen">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
</head>
<body>
<div class="wrap" ng-view>
</div>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script>
<script type="text/javascript" src="src/vendor/jquery.js"></script>
<script type="text/javascript" src="src/vendor/pouchdb.min.js"></script>
<script type="text/javascript" src="src/vendor/image-picker.min.js"> </script>
<script type="text/javascript" src="src/vendor/angular.min.js"></script>
<script type="text/javascript" src="src/vendor/angular.route.min.js"></script>
<script type="text/javascript" src="src/vendor/angular-cookies.js"></script>
<script type="text/javascript" src="src/app.js"></script>
<script type="text/javascript" src="src/services/AuthenticationService.js"></script>
<script type="text/javascript" src="src/controllers/AdminLoginController.js"></script>
<script type="text/javascript" src="src/controllers/AdminActionController.js"></script>
<script type="text/javascript" src="src/controllers/SetupController.js"></script>
<script type="text/javascript" src="src/controllers/SiteController.js"></script>
</body>
</html>
You can't access $routeProvider outside of .config
My guess would be that db.get is a call to your server which runs async. Then, by the time that call comes back, the routeProvider is already registered.
In other words, your code is being executed in the following order:
Create app (groovy)
Call CONFIG with $routeProvider (swell)
Call db.get(<callback>) (fine)
Manually setup $routeProvider.when with 6 specific routes (awesome)
.... Now, angularJs has been bootstrapped ...
db.get returns from the server and calls <callback> (uh-oh)
Attempting to access/change $routeProvider with new 'dynamic' routes (oops)
2 Potential Solutions:
A. bootstrap/config angularJs AFTER the db.get() returns. Never tried this ... I guess it could work, but seems risky.
B. DEFER route configuration using a decorator. there is an excellent blog post on this topic which seems to do what you want to do.
It would mean that all your dynamic routes would need the same "root" (eg - they all follow the format "/other/:route*"), but that's the only restriction.
I'd go with option B. Seems like a good plan!
Here is the structure:
Here are the sources:
/* #flow */
"use strict";
(function () {
const app = angular.module('Lesson2', ['ngRoute', 'ngAnimate'] );
app.config(function($routeProvider){
$routeProvider
.when('/what', { controller:'FavoCtrl', templateURL:'pages/what.html'})
.when('/where', { controller:'FavoCtrl', templateURL:'pages/where.html'})
.otherwise({redirectTo:'/what'});
});
app.controller('FavoCtrl', function ($scope) {
$scope.favouriteThings=[
{what:'raindrops', by:'on', where:'roses'},
{what:'whiskers', by:'on', where:'mittens'},
{what:'Brown paper packages', by:'tied up with', where:'strings'},
{what:'schnitzel', by:'with', where:'noodles'},
{what:'Wild geese', by:'that fly with', where:'the moon on their wings'},
{what:'girls', by:'in', where:'white dresses'},
{what:'Snowflakes', by:'that stay on', where:'my nose and eyelashes'}
];
})
})();
<!DOCTYPE html>
<html ng-app="Lesson2">
<head lang="en">
<link rel="stylesheet" type="text/css" href="styles/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="scripts/app.js"></script>
<meta charset="UTF-8">
<title>Lesson 2</title>
</head>
<body>
Hello!
<ng-view></ng-view>
</body>
</html>
And two "what.html" and "where.html" are plain texts, like This is "where.html"
The hardest thing here is that browser does not throw any error, console is clean. Views are not loaded, all I see is "Hello" of "index.html"
Seems like you have a typo, in your config block, use templateUrl instead of templateURL.
It should look like:
app.config(function($routeProvider){
$routeProvider
.when('/what', { controller:'FavoCtrl', templateUrl:'pages/what.html'})
.when('/where', { controller:'FavoCtrl', templateUrl:'pages/where.html'})
.otherwise({redirectTo:'/what'});
});
First you have a typo in your route configuration, it is "templateUrl" and not "templateURL".
If this doesn't solve your problem try adding the controller in your index.html
<html ng-app="Lesson2" ng-controller="FavoCtrl">
I'm using jquery bxslider on my first angular project. It is not working with template inside ng view. If use this one without ng view means it is working.
This is my HTML page:
<!doctype html>
<html ng-app="appSathya">
<head>
<meta charset="utf-8">
<title>Modest</title>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,700italic,400,600,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/jquery.bxslider.css">
</head>
<body>
<header ng-include='"template/header.html"'></header>
<section ng-view></section>
<script src="js/angular.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery.bxslider.js"></script>
<script src="js/main.js"></script>
</body>
</html>
and this is my javascript file
// JavaScript Document
var app = angular.module('appSathya', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
// Home
.when("/", {templateUrl: "partials/home.html", controller: "PageCtrl"})
}]);
app.controller('menuController', function($scope){
$scope.menus = [
{mitem:"Home", murl:"#/link"},
{mitem:"About", murl:"#/link"},
{mitem:"Work", murl:"#/link"},
{mitem:"Team", murl:"#/link"},
{mitem:"Services", murl:"#/link"},
{mitem:"Features", murl:"#/link"},
{mitem:"contact", murl:"#/link"}
];
});
app.directive('startslider',function() {
return {
restrict: 'A',
replace: true,
template: '<ul class="bxslider">' +
'<li ng-repeat="picture in pictures">' +
'<img ng-src="{{picture.src}}" alt="" />' +
'</li>' +
'</ul>',
link: function(scope, elm, attrs) {
elm.ready(function() {
$("." + $(elm[0]).attr('class')).bxSlider({
mode: 'fade',
pager: false,
autoControls: true
});
});
}
};
});
app.controller('PageCtrl', function($scope) {
$scope.pictures = [
{src:'img/banner.jpg' },
{src:'img/banner.jpg' },
{src:'img/banner.jpg' }
];
});
Change you order of script includes to this below:
<script src="js/jquery-1.9.1.js"></script>
<script src="js/angular.js"></script>
the reason that your code may malfunction angular has it's own version of jqlite and strips certain namespaces and attributes... but if you change the order angular has a function that recognize if jquery calls supercede the angular versions.
If all you need is to use a jQuery plugin inside Angular, then
the jQuery Passthrough directive should do it.
First include JQuery before AngularJS, then in jquery code use jQuery instead of $ since angular also uses $.
Some plugins not directly work with Angular. Ex:- Flexslider has separate JS which is compatible with AngularJS.
Here, you can solve your problem by looking at here
Have you tried placing your script src links in the header? Sure, it's sometimes required to place them in the footer, but if you want them to fire before anything else, play about with the order. Looking at the code, I'd suggest placing your <script src="js/jquery-1.9.1.js"></script><script src="js/jquery.bxslider.js"></script> tags in the head?
I have an AngularJS app. I want this app to run both in the browser and be able to distribute it with PhoneGap. In an attempt to do this, I have the following code:
index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/app/app.js"></script>
</head>
<body>
...
<script type="text/javascript">
if (window.location.protocol === "file:") {
document.addEventListener('deviceready', startApp, false);
} else {
startApp();
}
</script>
</body>
</html>
app.js
function startApp() {
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function() {
...
});
myApp.run(function() {
...
});
}
controller.js
"use strict";
myApp.controller('MyController', function($rootScope, $scope, $location) {
...
});
myApp.controller('MyOtherController', function($rootScope, $scope, $location) {
...
});
...
If I add controllers.js after app.js in the head tag, I get an error that says:
Uncaught ReferenceError: myApp is not defined
This is happening because I'm manually bootstrapping the AngularJS app. I need to manually bootstrap it because of my need to startApp. For this reason, I need a way to dynamically load controllers.js from within startApp. Yet, I'm not sure how to do that. Can anyone provide some help?
THank you
you have missed ng-app="" attribute in html tag...
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script type="text/javascript" src="/app/app.js"></script>
</head>
<body>
...
<script type="text/javascript">
if (window.location.protocol === "file:") {
document.addEventListener('deviceready', startApp, false);
} else {
startApp();
}
</script>
</body>
</html>
Why don't you give requirejs a try?
He has a strong dependency management based loader and will avoid issues like this.
First thing first: To initialize your app angular module its require angular-route.js with angular.js file and these js file should be loaded before your app js.
<head>
<script type="text/javascript" src="/app/angular.js"></script>
<script type="text/javascript" src="/app/angular-route.js"></script>
<script type="text/javascript" src="/app/app.js"></script>
</head>