I have just started out attempting to use Webpack to bundle my Angular App. When I have included the essentials I am getting the following error
Argument 'fn' is not a function, got string
I think it's something to do with Angular-Route, but I can't find anything I can see what would be wrong.
My stripped down files are as follows:
./index.html
<!DOCTYPE html>
<html lang="en" ng-app="crewGui">
<head>
<title>GUI</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/stylesheets/styles.css">
<script src="js/dist/vendor.bundle.js"></script>
<script src="bower_components/Chart.js/Chart.js"></script>
<script src="bower_components/angular-chart.js/dist/angular-chart.js"></script>
<script src="bower_components/angular-busy/dist/angular-busy.min.js"></script>
<script src="js/dist/app.bundle.js"></script>
</head>
<body class="container-fluid">
<header class="row">
<div class="logo col-xs-6">
<img src="images/logo_alt.png" class="img-responsive" alt"logo">
</div>
</header>
<div id="content">
<div class="container-fluid">
<ng-view></ng-view>
</div>
</div>
<footer class="row">
<div class="copyright col-xs-12">©</div>
</footer>
</body>
</html>
./module.js
'use strict';
var angular = require('angular');
var ngRoute = require('angular-route');
angular
.module('crewGui', [
'ngRoute'
]
);
require('./');
require('./services');
require('./controllers');
./index.js
'use strict';
var angular = require('angular');
var ngRoute = require('angular-route');
angular
.module('crewGui')
.config('Config', require('./config'))
.run('Run', require('./run'));
./run.js
'use strict';
Run.$inject = ['$http'];
function Run($http) {
$http.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
$http.defaults.headers.common['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT';
$http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
$http.defaults.headers.common['Accept'] = 'application/json';
$http.defaults.headers.common.Authorization = "Basic AWORKINGAPIKEY";
};
module.exports = Run;
./config.js
'use strict';
Config.$inject = ['$routeProvider'];
function Config($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/dashboard.html',
controller: 'DashboardController',
controllerAs: 'dashboard'
})
.otherwise({
redirectTo: '/'
});
};
module.exports = Config;
./services/index.js
'use strict';
var angular = require('angular');
var ngRoute = require('angular-route');
angular
.module('crewGui')
.service('GetData', require('./get_data_service'));
./services/get_data_service.js
'use strict';
GetData.$inject = ['$http'];
function GetData($http) {
var self = this;
self.getData = function() {
return $http.get("https://aworkingurl")
.success(function (data, status, headers, config) {
return data;
})
.error (function (data, status, headers, config) {
return status;
});
};
};
module.exports = GetData;
./controllers/index.js
'use strict';
var angular = require('angular');
var ngRoute = require('angular-route');
angular
.module('crewGui')
.controller('DashboardController', require('./controller_dashboard'));
./controllers/controller_dashboard.js
'use strict';
DashboardController.$inject = ['$scope', 'GetData'];
function DashboardController($scope, GetData) {
var self = this;
GetData.getData()
.then(function(data){
self.flightData = data.data;
});
};
module.exports = DashboardController;
Any constructive help would be much appreciated. Please let me know if there;'s anything else you need. And i probably don't need to be requiring ngRoute all over the place. Clutching at straws at this point.
Many thanks.
In index.js try removing 'Config' and 'Run' so the lines look like this:
.config(require('./config'))
.run(require('./run'));
The error was suggesting that the first argument needs to be a function instead of a string :)
For everyone who comes here looking for a solution to the error, please check your global variables in the console, and the name of your remotes for collision. For us, the problem was that we called our remote navigator, but in the global context, there was already a variable defined with that name.
Related
app.js
(function(){
'use strict';
angular
.module('app', ['ngRoute', 'ngCookies'])
.config(config)
config.$inject = ['$routeProvider', '$locationProvider'];
function config($routeProvider, $locationProvider){
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'home/home.html',
controllerAs: 'vm'
})
}
})();
home.controller.js
(function () {
'use strict';
angular
.module('app')
.controller('HomeController', HomeController);
HomeController.$inject = ['UserService', '$rootScope'];
function HomeController(UserService, $rootScope) {
$rootScope.bodylayout ='main_page_que';
var vm = this;
}
})();
home.js
var app = angular.module('app', []);
app.controller('RedCtrl', function($scope) {
$scope.OpenRed = function() {
$scope.userRed = !$scope.userRed;
$scope.userBlue = false;
}
$scope.HideRed = function() {
$scope.userRed = false;
}
$scope.OpenBlue = function() {
$scope.userBlue = !$scope.userBlue;
$scope.userRed = false;
};
$scope.HideBlue = function() {
$scope.userBlue = false;
};
});
home.html
<div ng-controller="RedCtrl">
Show Red
<div hide-red="HideRed()" class="loginBox" ng-show="userRed"></div>
Show Blue
<div hide-blue="HideBlue()" class="loginBoxBlue" ng-show="userBlue"></div>
</div>
Index.html
<html lang="pl" ng-app="app">
<body class="{{bodylayout}}">
<div class="content">
<div ng-view style="margin:auto"></div>
</div>
<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="//code.angularjs.org/1.6.0/angular.min.js"></script>
<script src="//code.angularjs.org/1.6.0/angular-route.min.js"></script>
<script src="//code.angularjs.org/1.6.0/angular-cookies.min.js"></script>
<script src="home.js"></script>
<script src="app.js"></script>
<script src="authentication.service.js"></script>
<script src="flash.service.js"></script>
<script src="user.service.local-storage.js"></script>
<script src="home/home.controller.js"></script>
</body>
</html>
Hey, this is part from application when I use ngRoute and dynamically add home.html, but I think I have wrong app.js or home.controller.js beacuse when I add external file home.js (when is ng-controller=""RedCtrl. I get error [$controller:ctrlreg] RedCtrl is not register. Have you ideas why? I am new in Angular and I think the main reason is lack of my knowledge.
You are overwriting app module in home.js thus getting the error
Use
var app = angular.module('app'); //Get previously defined module
instead of
var app = angular.module('app', []); //It declares new module
You also need to change the sequence of JavaScript files
<script src="app.js"></script>
<script src="home.js"></script>
I have 2 html file and I want to pass parameters via angular service between them.
these are the files I have:
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl2">
</div>
enter here
<script>
var app=angular.module("myApp");
app.controller("myCtrl2", ['$scope','$location', 'myService',
function($scope, $location, myService) {
myService.set("world");
}]);
</script>
</body>
</html>
enter2.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl3">
hello {{x}}
</div><script type="text/javascript">
var app=angular.module("myApp");
app.controller("myCtrl3", ['$scope','$location', 'myService',
function($scope, $location, myService) {
$scope.x=myService.get();
}]);
</script>
</body>
</html>
services.js
var app=angular.module("myApp", []);
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
why can't I get "hello world" in enter2.html, but instead get "hello" (x is not found by service)...?
When you go from index.html to enter2.html the whole page loads from scratch. For the data that you are expecting to stay in the browser, you might need to use advanced angular concepts such as loading just a part of the page using ng-view.
If that's something you have already overruled, saving the data in the service somewhere (may be the browser session) before unloading (window.onunload event) the page and then loading it back from there when the service loads (window.onload event) could also work.
Here is a working example based on your code.
I kept your index.html and added ui-view to have a single page application. The app uses 'ui.router'.
In the myCtrl2 I saved the data in the service, and call it back from myCtrl3:
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
To keep things simple, I have one Javascript file:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'myCtrl2',
controllerAs: 'vm'
})
.state('enter2', {
url: '/enter2',
templateUrl: 'enter2.html',
controller: 'myCtrl3',
controllerAs: 'vm'
});
})
.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
I also uses the var vm=this and ControllerAs as often recommended to avoid $scope issues.
index.html looks like below... pleaes note the ui-sref instead of href:
<div ui-view="">
<a ui-sref="enter2">Enter here</a>
</div>
enter2.html is now just the div part and your content:
<div>
Hello {{ vm.x }}
</div>
Let us know if that helps.
Additional info:
AngularJS Routing Using UI-Router
AngularJS's Controller As and the vm Variable
Sounds like you need to use a controller for your view page
https://docs.angularjs.org/guide/controller
Error only if minimized and loaded in same file.
If app.ts is loaded before Service or Directive it works.
(No problems with controllers)
How can i make it work?
Console Error:
site.js:119 Error: [$injector:unpr] http://errors.angularjs.org/1.5.0/$injector/unpr?p0=eProvider%20%3C-%20e%20%3C-%20routeNavigation%20%3C-%20navigationDirective
at Error (native)
at http://localhost:50308/js/site.js:11:416
at http://localhost:50308/js/site.js:48:7
at Object.d [as get] (http://localhost:50308/js/site.js:45:270)
at http://localhost:50308/js/site.js:48:69
at d (http://localhost:50308/js/site.js:45:270)
at e (http://localhost:50308/js/site.js:46:1)
at Object.invoke (http://localhost:50308/js/site.js:46:86)
at Object.$get (http://localhost:50308/js/site.js:43:460)
at Object.invoke (http://localhost:50308/js/site.js:46:295)(anonymous function) # site.js:119
AngularJs Error Message:
Unknown provider: eProvider <- e <- routeNavigation <- navigationDirective
app.ts
enter code here
"use strict";
var app = angular.module('HouseConcertApp', ['ngCookies', 'pascalprecht.translate', 'ngRoute', 'houseconcertControllers', 'houseconcertServices', 'houseconcertDirectives']);
app.config([
'$translateProvider', '$routeProvider', function($translateProvider, $routeProvider) { ....
services.ts
var houseconcertServices = angular.module('houseconcertServices', []);
houseconcertServices.factory('routeNavigation', function ($route, $location) {
var routes = [];
angular.forEach($route.routes, function (route, path) {
if (route.name) {
routes.push({
path: path,
name: route.name
});
}
});
return {
routes: routes,
activeRoute: function (route) {
return route.path === $location.path();
}
};
});
directives.ts
var houseconcertDirectives = angular.module("houseconcertDirectives", []);
houseconcertDirectives.directive('navigation', ['routeNavigation', routeNavigation => ({
restrict: "E",
templateUrl: "navigation-directive-tpl.html",
controller($scope) {
$scope.routes = routeNavigation.routes;
$scope.activeRoute = routeNavigation.activeRoute;
}
})]);
index.html
<!doctype html>
<html ng-app="HouseConcertApp">
<head>
<base href="/index.html">
<title>House Concert</title>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/Main.css"/>
<script src="js/site.js" onload="Hc.Common.initialize()"></script>
</head>
<body>
<navigation></navigation>
<div ng-controller="HouseConcertCtrl">
<div ng-view></div>
</div>
</div>
</body>
</html>
it works if html head script includes like this:
but not if all in this order minimized in site.js (with gulp)
<script src="pathToFolder/app.ts"></script>
<script src="pathToFolder/services.ts"></script>
<script src="pathToFolder/controllers.ts"></script>
<script src="pathToFolder/directives.ts"></script>
To get files minified without error you should make sure to follow Dependency Injection pattern consistently. Only routeNavigation factory code is missing DI Inline Array annotation in your code.
Change below
houseconcertServices.factory('routeNavigation', function ($route, $location) {
to
houseconcertServices.factory('routeNavigation',['$route', '$location',
function ($route, $location) {
//service code will be as is.
}]);
Doc link for minification related warning
Trying to build a simple application that allows a user to upload a file, and upon clicking the 'add' button, It parses the file and displays the result within the browser.
I am using IntelliJ to generate the AngularJS application stub, and modifying it accordingly.
My attempt is below:
view1.html
<!DOCTYPE html>
<html lang="en" ng-app>
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="../app.css">
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/ng-file-upload/ng-file-upload-shim.js"></script> <!-- for no html5 browsers support -->
<script src="bower_components/ng-file-upload/ng-file-upload.js"></script>
<!--<script src="view1.js"></script>-->
</head>
<body>
<div ng-controller="View1Ctrl">
<input type="file" id="file" name="file"/>
<br/>
<button ng-click="add()">Add</button>
<p>{{data}}</p>
</div>
</body>
</html>
view1.js
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function ($scope) {
$scope.data = 'none';
$scope.add = function() {
var f = document.getElementById('file').files[0],
r = new FileReader();
r.onloadend = function(e) {
$scope.data = e.target.result;
}
r.readAsArrayBuffer(f);
}
}]);
view1_test.js
'use strict';
describe('myApp.view1 module', function() {
beforeEach(module('myApp.view1'));
describe('view1 controller', function(){
it('should ....', inject(function($controller, $rootScope) {
//spec body
// var view1Ctrl = $controller('View1Ctrl');
var $scope = $rootScope.$new(),
ctrl = $controller('View1Ctrl', {
$scope: $scope
// $User: {}
});
expect(ctrl).toBeDefined();
}));
});
});
app.js
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
I am not sure where I could potentially be going wrong? I viewed quite a few questions to this and tried multiple different approaches but I cannot get this to work despite all of my tests passing.
The issue was around my view1.js file. I found the Papa Parse library extremely useful.
Here is my solution used from the open source Papa Parse community:
Papa.parse(fileInput[0], {
complete: function(results) {
console.log("Complete!", results.data);
$.each(results.data, function(i, el) {
var row = $("<tr/>");
row.append($("<td/>").text(i));
$.each(el, function(j, cell) {
if (cell !== "")
row.append($("<td/>").text(cell));
});
$("#results tbody").append(row);
});
}
});
I would like to use i18n and i10n in my Angular app.
I read that Angular-translate can help with this, however, it doesn't work for me.
In my index.html:
<!DOCTYPE html>
<html ng-app="eApp">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="../common/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="../common/css/style.css" />
<title></title>
</head>
<body ng-controller="AppCtrl">
<div id="container" ng-view></div>
<!--- Libs Js files --->
<script type="text/javascript" src="../vendor/angularjs/angular.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-route.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-translate.min.js"></script>
</body>
</html>
In my eApp.js:
var eApp = angular.module('elbitApp', ['ngRoute', 'ui.bootstrap', 'config', 'pascalprecht.translate']);
// configure our routes
eApp.config(["$routeProvider",
function ($routeProvider) {
$routeProvider
// route for the home page
.when('/c', {
templateUrl: 'c/partials/c.html',
controller: 'CController'
})
// route for the about page
.when('/de', {
templateUrl: 'd/partials/dE.html',
controller: 'DEController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
})
// route for the contact page
.when('/di', {
templateUrl: 'd/partials/di.html',
controller: 'DIController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
}).otherwise({
redirectTo: '/di'
});
}]).config(["$httpProvider",
function ($httpProvider) {
// Configure the $httpProvider to parse date with date transformer
$httpProvider.defaults.transformResponse.push(function (responseData) {
convertDateStringsToDates(responseData);
return responseData;
});
}]).config(["$translateProvider",
function ($translateProvider) {
$translateProvider.translations('en', {
"TITLE": 'Hello',
"FOO": 'This is a paragraph.',
"BUTTON_LANG_EN": 'english',
"BUTTON_LANG_DE": 'german'
});
$translateProvider.translations('de', {
"TITLE": 'Hallo',
"FOO": 'Dies ist ein Paragraph.',
"BUTTON_LANG_EN": 'englisch',
"BUTTON_LANG_DE": 'deutsch'
});
$translateProvider.preferredLanguage('en');
}]);
// main controller that catches resolving issues of the other controllers
eApp.controller('AppCtrl', function ($rootScope) {
$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
alert("Cant resolve the request of the controller "); //TODO: add URL + additional data.
})
});
In this file I defined my app and added the $translateProvider and two dictionaries.
Afterwards I got to my deController.js:
eApp.controller('DispatcherEventsController', ['$scope', '$route', '$translate',
function($scope, $route, $translate){
var data = $route.current.locals.data;
$scope.title = $translate.instant("FOO");
$scope.switchLanguage = function(languageKey){
$translate.use(languageKey);
};
}]);
In de.html I added a h1 tag with FOO and in a click I would like to change to German:
<h1>{{title |translate}}</h1>
<h1 translate="{{title}}"></h1>
<button type="button" id="searchButton" class="btn btn-default" ng-click="switchLanguage('de')">German</button>
I don't get any problem, but nothing happens. I expected that the English title will be converted to German title.
What can I do to make this work?
It works well for me. Here is a jsFiddle DEMO.
In this case, you want to bind $scope.title with translation key "FOO".
You should change the value of $scope.title dynamically in the switchLanguage function. Then view will be updated accordingly.
//default value
$scope.title = $translate.instant("HEADLINE");
$scope.switchLanguage = function(key){
$translate.use(key);
$scope.title = $translate.instant("HEADLINE");
}
In my opinion, maybe use translation key is a better way than scope data binding. You don't have to maitain the value of key manually.
<h1>{{'FOO' | translate}}</h1>
According to the error msg you provided, maybe you could check if there is any typo syntax in your controller.
Should be
$translate.use(languageKey)
Not
$translate.uses(languageKey)
Though not directly related to your question - you must remember to set the preferred language in the translations.js file, or whatever its name is that you define your key-value translations. Otherwise it will just default to whatever the key is.
...
GREETING: 'Hello World!',
...
$translateProvider.preferredLanguage('en');
Without this line, when doing this:
<h2>{{'GREETING'|translate}}</h2>
Would appear as just GREETING instead of the 'Hello World.'