I have started working an app using angularjs which can have have different UI themes.
index.html
<html lang="en" data-ng-app="appConfigurator">
<head>
<title>The title</title>
</head>
<body data-ng-controller="appCtrl">
<div data-ng-view></div>
</body>
<script type="text/javascript" src="libs/angular.js"></script>
<script type="text/javascript" src="libs/angular-route.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/services/webservice.js"></script>
<script type="text/javascript" src="js/controllers/appCtrl.js"></script>
<script type="text/javascript" src="js/router.js"></script>
</html>
app.js - Here I initialize my module and also declare a global variable 'theme'.
var appConfigurator = angular.module("appConfigurator", ['ngRoute']);
var theme = "";
webservice.js - This service make Web service calls to the backend and gets the data as response.
appConfigurator.factory('webService', function($http) {
return {
callService : function(method, fileType, rowId, data, message, type) {
return $http({
method : method,
url : url,
data : "Message=" + message + "&XMLData=" + data + "&Type=" + type,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
}
});
}
};
});
appCtrl.js - This is the main app controller. Here I am making a webservice call to get the data and then using this data I will have to make one more call to get the name of the "theme" I need to use. So basically two calls.
appConfigurator.controller("appCtrl", function($scope, webService) {
$scope.succ = function(res) {
//alert("success" + res.name);
};
$scope.err = function(res) {
alert("error");
}
webService.callService('POST', 'data', 'ID', '', 'Message','XML').success($scope.succ).error($scope.err);
});
router.js - Based on the value of theme the route will route to the particular folder structure which will contain the theme specific HTML, CSS and JS files.
appConfigurator.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/Config', {
templateUrl: 'themes/'+theme+'/views/a.tmpl.html',
controller: ''
}).otherwise({
redirectTo: '/Config'
});
}
]);
The obvious problem is that by the time routers sets the path for the tempelateUrl I don't have the name of the theme.
Solutions -
1) One solution (this one works) is to get the theme name in the URL as a parameter but that cannot be done on the backend side. So there is no point of this solution.
2) Is there a way I can delay the routing process so that by the time angular tries to route I have the theme name.
The development is in very initial stage. Comments to change the approach will also be helpful. And yes Angularjs is all new to me and my peers.
appConfigurator.config(['$routeProvider', function($routeProvider) {
// set theme name
var theme = 'theme_name';
$routeProvider.when('/Config', {
templateUrl: 'themes/'+theme+'/views/a.tmpl.html',
controller: ''
}).otherwise({
redirectTo: '/Config'
});
}
]);
Related
I'm new to angularjs and followed the tutorial here from w3schools to create my first simple Angularjs app and it worked fine. After going through the official angularjs tutorial I decided to modularize my app but now its not working. Currently I m getting the error
"The controller with the name 'redController' is not registered."
I want to display a message in component 'red' using its controller. I tried altering many parts of the code only to get new errors and it seems I have messed up modularizing :|
I'm using v1.6.9
Here is my directory structure
app/
scripts/
angular.min.js
angular-route.js
blue/
blue.template.html
red/
red.template.html
red.module.js
red.component.js
app.config.js
app.module.js
index.html
and source files :
app.config.js
angular
.module("myApp", [ 'red','ngRoute' ])
.config(function($routeProvider) {
$routeProvider
.when("/red", {
templateUrl : "red/red.template.html",
controller: "redController"
})
.when("/blue", {
templateUrl : "blue/blue.template.html"
});
});
app.module.js
angular.module('myApp', [
'red',
'ngRoute'
]);
index.html
<!DOCTYPE html>
<html>
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="red/red.module.js"></script>
<script src="red/red.component.js"></script>
<body ng-app="myApp">
Red
Blue
<div ng-view></div>
<p>Click on the links to navigate "</p>
</body>
</html>
red.template.html
<h1>red</h1>
<p>{{msg}}</p>hell
red.module.js
angular.module('red', [ 'ngRoute' ]);
red.component.js
angular.module('red').component('red',{
templateUrl: 'red/red.template.html',
controller: function redController() {
this.msg = "this is red";
console.log("Hi");
}
});
You are delcaring the module again and again in each .js files, declare only in one .js file and use it in rest of the fields.
change your red.module.js as,
angular.module('red', []);
your app.config.js should be as,
angular
.module("myApp")
.config(function($routeProvider) {
$routeProvider
.when("/red", {
templateUrl : "red/red.template.html",
controller: "redController"
})
.when("/blue", {
templateUrl : "blue/blue.template.html"
});
});
and change the order as follows,
<script src="red/red.module.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="red/red.component.js"></script>
Change red.component.js as follows
angular.module('red')
.component('red',{
templateUrl:
'red/red.template.html',
})
.controller("redController",function($scope)
{
$scope.msg ="This is red";
});
First of all, as #Sajeetharan you're defining the myApp module twice. Inside your app.config.js and also in app.module.js. If you use angular.module with 2 parameters angular.module('app', []) you're setting the module, if you use angular.module('app') it'll work as a getter. So, in your app.config.js you should use the getter to configure your app.
Once you did that, you can configure your route to something like this:
angular.module('myApp').config(function($routeProvider){
$routeProvider.when('/red', { template: '<red></red>'});
})
I would use this approach since you defined the component in another module.
If you still want to use the approach you've implemented to set both the templateUrl and controller in the $routeProvider, you'll have to change your red component declaration to something like this:
angular.module('red')
.component('red', { templateUrl: 'red/red.template.html'})
.controller('redController', function(){
this.msg = 'This is red.';
});
I'vent tested this second approach as for me the first makes more sense.
In a real-life project, I'm trying to populate an Angular ui-grid using WebAPI to get JSON data has HTML content. So far, the column has HTML is either showing them as plain text or blank content.
Followed this still not getting it work:
How to render html formatted content in ng-grid?
Here are my code:
Index.html (script are downloaded to local)
<script type="text/javascript" src="/scripts/jquery-1.7.2.min.js"></script>
<script src="/scripts/angular-1.5.0.js"></script>
<script src="/scripts/angular-touch-1.5.0.js"></script>
<script src="/scripts/angular-animate-1.5.0.js"></script>
<script src="/scripts/angular-sanitize-1.5.0.min.js"></script>
<script src="/scripts/angular-bind-html-compile.js"></script>
<script src="/scripts/csv.js"></script> <!-- 2013 -->
<script src="/scripts/pdfmake.js"></script>
<script src="/scripts/vfs_fonts.js"></script>
<script src="/scripts/ui-grid.min.js"></script> <!-- v3.2.9-->
<link rel="stylesheet" type="text/css" href="/content/ui-grid.css"/><!-- v3.2.9 - 2016-09-21-->
<script src="/scripts/myAngular.js"></script>
<div ng-controller="getHomeMsg">
<div id="grid1" ui-grid="grdAngHomeMsg" class="Agrid"></div>
</div>
myAngular.js
var myApp = angular.module('app', ['ngTouch', 'ui.grid', 'ngSanitize', 'angular-bind-html-compile']);
myApp.controller('getHomeMsg', function($scope, $http, $sce) // prefix function() with ['$scope', '$http', '$sce', ... got the same result
{
$scope.grdAngHomeMsg = {};
$scope.grdAngHomeMsg.columnDefs = [
{
name: 'Subject',
cellTemplate: '<div class="ui-grid-cell-contents" bind-html-compile="COL_FIELD"></div>' //'<div ng-bind-html="row.entity[col.field]"></div>'
},
{
name: 'Message'
},
];
var msgData;
$http(
{
method: 'GET',
url: '/API/HomeMsg',
responseType: 'json'
}).then(function successCallback(response) {
msgData = $scope.grdAngHomeMsg.data = response.data;
$scope.grdAngHomeMsg.data.forEach(function (d) {
$sce.trustAsHtml(d.Subject); // F12 shows d.Subject has value and valid!
});
}, function errorCallback(response, statusText) {
alert(statusText);
});
// also tried replacing this cellTemplate bind-html-compile="COL_FIELD" with ng-bind-html="AA(COL_FIELD)", F12 shows this function is never called
$scope.AA = function (htm) {
return $sc.trustAsHtml(htm);
};
// it never reach here after actual API call
//msgData.forEach(function (d) {
// $sce.trustAsHtml(d.Subject);
//})
}
);
Browser = FireFox v50.1.
F12 verified data returned are in perfect JSON format.
F12 shows no error during execution, all scripts are loaded, $sce object is instantiated w/ properties including trustAsHtml method.
Other articles/examples tried including:
How do you use $sce.trustAsHtml(string) to replicate ng-bind-html-unsafe in Angular 1.2+
https://github.com/angular-ui/ui-grid/issues/1292
Spent two full days, appreciate any help!
I am trying to set up a project using gulp and browser sync with angularjs. I cannot get browser sync to work correctly when I use the ng-view tag in my index.html file. This is the error I get in my browser console when I run browser sync:
Uncaught TypeError: Cannot read property 'data1457531805746' of null
coming from browser-sync-client.2.11.1.js:204 It works as expected, page loads fine, when ng-view/ngRoute is not used.
These are my files:
./gulpfile.js
// Spin up a server
gulp.task('browserSync', function() {
browserSync.use(spa({
selector: "[ng-app]" //Only needed for angular apps
}));
browserSync.init({
port: 8080,
server: {
baseDir: path.src
}
})
});
// Watch for changes in files
gulp.task('watch', ['browserSync'], function() {
// Watch .js files -- removed for brevity
});
// Default Task
gulp.task('default', ['watch']);
./app/controllers/controllers.js
'use strict';
/* Controllers */
var dc4SearchControllers = angular.module('dc4SearchControllers', []);
dc4SearchControllers.controller('CompanySearchCtrl', ['$scope', '$http',
function($scope, $http){
$scope.test = 'Hello, world!';
}]);
./app/index.html
<html ng-app="dc4SearchApp">
<head>
<link href="/bower_components/webui-core/dist/webui-core.min.css" rel="stylesheet">
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/bower_components/angular-route/angular-route.min.js"> </script>
<script src="/bower_components/lodash/lodash.min.js"></script>
<script src="/bower_components/webui-core/dist/webui-core.min.js"></script>
<script src="app.js"></script>
<script src="controllers/controllers.js"></script>
</head>
<body ng-view>
</body>
</html>
./app/app.js
'use strict';
/* App Module */
var dc4SearchApp = angular.module('dc4SearchApp', [
'ngRoute',
'dc4SearchControllers'
]);
dc4SearchApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/company-search', {
templateUrl: 'views/company-search.html',
controller: 'CompanySearchCtrl'
}).
otherwise({
redirectTo: '/company-search'
});
}]);
./app/views/company-search.html
<div ng-controller="CompanySearchCtrl">
{{test}}
<div class="spinner spin"> </div>
</div>
I am hoping this is just something silly and easy that I am over looking and haven't tried yet! Thanks in advance.
"Browsersync works by injecting an asynchronous script tag right after the body tag during initial request. In order for this to work properly the body tag must be present. Alternatively you can provide a custom rule for the snippet using snippetOptions"
https://www.npmjs.com/package/browser-sync
It seems Browsersync is reloading the body tag. Have you tried moving the ng-view to another child div ?
I'm new to angular, so apologies if this has an obvious answer. I want to display a blog post title and its published date, as the start date, on the ui-calendar. It works fine with hardcoded start, end and title values but nothing is returned when in the success directive when I make a jsonp call.
The jsonp call works fine if I don't use the calendar, so I think it's a syntax issue.
This is my angular code (with hard-coded dates):
var MyController = function($scope) {
$scope.uiConfig = {
...
};
$scope.eventSources = [$scope.events];
$scope.events = [
{
start : '2015-04-20',
end : '2015-04-21',
type: "GET",
url: 'http://calendar.jacarandatech.com/wp-json/posts/5/?_jsonp=?',
dataType: 'jsonp',
success: function(response) {
//what do I put here to display the response.title??
}
}
]
};
angular
.module('MyApp', ['ui'])
.controller('MyController', MyController);
and my html code:
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<link rel="stylesheet" href="bower_components/fullcalendar/fullcalendar.css"/>
<script src="http://code.jquery.com/jquery-1.7.1.js"></script>
<script src="http://code.angularjs.org/1.0.1/angular-1.0.1.js" ng:autobind></script>
<script type="text/javascript" src="bower_components/angular-resource/angular-resource.js"></script>
<script src="http://www.dillingermediaonline.com/angular-ui.js"></script>
<script type="text/javascript" src="bower_components/jquery-ui/ui/jquery-ui.js"></script>
<script type="text/javascript" src="bower_components/angular-ui-calendar/src/calendar.js"></script>
<script type="text/javascript" src="bower_components/fullcalendar/fullcalendar.js"></script>
<script type="text/javascript" src="bower_components/fullcalendar/gcal.js"></script>
<script type="text/javascript" src="app.js"></script>
<title>ng calendar</title>
</head>
<body>
<div ng-controller="MyController" calendar="calendar" ui-calendar="uiConfig.calendar" ng-model="eventSources"></div>
</body>
</html>
jsonp code (works fine):
$.ajax({
type: "GET",
url: 'http://calendar.jacarandatech.com/wp-json/posts/5/?_jsonp=?',
dataType: 'jsonp',
success: function (response) {
var posttitle = response.title;
var timestamp = response.modified_gmt;
console.log('post title = ' + posttitle);
console.log('timestamp = ' + timestamp);
}
});
I researched the following stackoverflow questions but couldn't get their solutions to work:
How do I use jsonp with angular-ui calendar
Angular JSONP calling WordPress JSON REST API
You need to make sure that the variables that contain the title and the timestamp are within the controller's scope.
First, in the first line add $http in the controller like this:
var MyController = function($scope, $http) {
then declare the variables:
$scope.postTitle = '';
$scope.postTimestamp = '';
You should use $http to make the AJAX call. The other function you showed is not needed.
$http.get('http://calendar.jacarandatech.com/wp-json/posts/5/?_jsonp=?').success(function (res) {
$scope.postTitle = res.title;
$scope.postTimestamp = res.modified_gmt;
});
This will let you declare the calendar event like this:
start : $scope.postTimestamp,
title : $scope.postTitle
I am having trouble setting up ng-view. This is my first mean stack app. I got everything working within index.html. However, when I set up ng-view I am getting errors stating that I have my javascripts in a public folder. My index.html is in the html folder. I have set up an additional folder in views called templates to house my additional pages
"GET http://localhost:3000/templates/home.html 500 (Internal Server Error)"
Inside of my html I have set up ng-view
<!doctype html>
<html lang="en" ng-app='myApp'>
<head>
<meta charset="UTF-8">
<title>Caffeine app</title>
<!-- styles -->
<link href="http://netdna.bootstrapcdn.com/bootswatch/3.3.2/yeti/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="stylesheets/style.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container>
<div ng-view>
</div>
</div>
<!-- scripts -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<script src="javascripts/main2.js" type="text/javascript"></script>
</body>
</html>
In my public js folder I have set up my factory, config, and controllers. I am using swig.
var app = angular.module('myApp', ['ngRoute'], function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/home',{
templateUrl:'templates/home.html',
controller:'myController'
})
.when('/drinkLibrary',{
templateUrl:'templates/drinkLibrary.html',
controller:'DrinkLibraryController'
})
.otherwise({
redirectTo: '/home'
})
$locationProvider.hashPrefix('!');
});
app.factory('Drink',function($http) {
var Drink = function(name,description,caffeineLevel) {
this.name = name;
this.description = description;
this.caffeineLevel = caffeineLevel;
}
return Drink;
})
app.controller('HomeController',function($scope){
console.log('home');
})
app.controller('DrinkLibraryController',function($scope){
console.log('drinkLibrary');
})
app.controller('myController', function($scope,Drink,$http ) {
var init = function() {
$scope.defaultForm = {
beverageName: "",
description: "",
caffeine: ""
};
}
init();
// $scope.defaultForm = defaultForm;
$scope.allDrinkList = [];
$scope.drinkList= function(obj) {
var newdrink = new Drink(obj.beverageName,obj.description,obj.caffeine);
$scope.allDrinkList.push(newdrink);
console.log($scope.allDrinkList);
init();
$http.post('/api/drinks',obj).
success(function(data){
console.log(data)
$scope.message = 'success';
}).
error(function(data){
console.log('error');
})
};
});
Inside of my routes folder I am making sure to render the index
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
In doing a mean stack I must remember to set up routes on the server and client side. My templates are in the view. I am rendering my view through express I need to also render my templates in the same manner.
app.use('templates/:templateid', routes);
I am using the express generator so through the routes I called a get request and set the url to the templates folder. Next, I identified the template id as a param. This saves me from setting up each page ex(home,library, about).
router.get('/templates/:templateid' ,function(req,res,next){
res.render('templates/' + req.params.templateid);
})