AngularJS filter in controller - angularjs

I have this angular loop and controller:
<li class="list-group-item" ng-repeat="post in posts | filter: post._creator = getCurrentUser"></li>
and Controller:
$http.get('/api/posts').success(function(posts) {
$scope.posts = posts;
$scope.getCurrentUser = Auth.getCurrentUser()._id;
});
It is possible to inject the filter in the controller?
What is the best practice?

I created a dedicated file filers.js and put filters registration code into the file.
'use strict';
angular.module('ftFilters', [])
.filter('rub', function() {
return function (value) {
if (value === undefined || value === null){
return 'не задана';
}
return value.toFixed(2).toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 ").replace('.','<small>,') + '</small> руб';
};
})
.filter('rudate', function($filter) {
var angularDateFilter = $filter('date');
return function(theDate) {
return angularDateFilter(theDate, 'dd.MM.yy HH:mm:ss');
}
});
then you must add this module into dependencies for your application, e.g.
'use strict';
// Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() {
// Init module configuration options
var applicationModuleName = 'ft';
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize',
'ui.router', 'ui.bootstrap', 'ui.utils', 'vr.directives.slider', 'ya.treeview', 'ui.select', 'ftFilters' ];
// Add a new vertical module
var registerModule = function(moduleName) {
// Create angular module
angular.module(moduleName, []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
return {
applicationModuleName: applicationModuleName,
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
registerModule: registerModule
};
})();
after this you can use it everywhere

Related

AngularJS file upload Error: $injector:unpr Unknown Provider

I am trying to do a file upload using angularjs. But I am getting this error for the past few days and I am unable to resolve:
angular.js:13920 Error: [$injector:unpr] http://errors.angularjs.org/1.5.8/$injector/unpr?p0=fileUploadServiceProvider%20%3C-%20fileUploadService%20%3C-%20appCtrl
at angular.js:38
at angular.js:4511
at Object.d [as get] (angular.js:4664)
at angular.js:4516
at d (angular.js:4664)
at e (angular.js:4688)
at Object.invoke (angular.js:4710)
at S.instance (angular.js:10354)
at p (angular.js:9263)
at g (angular.js:8620)
I only want to read the files uploaded, and store it in the server, and not to link to other URL. I am using Django for my backend. This are my codes:
HTML
<body ng-app="myApp">
<div ng-controller="appCtrl">
<input type="file" id="file" name="files" accept="text/*"
data-url="file" class="upload" ng-model="uploadFile"/>
<label for="file">
<span class="glyphicon glyphicon-open" id="selectFile">
</span>Select a file
</label>
</div>
</body>
<script src="../static/js/services/fileUploadService.js"></script>
<script src="../static/js/controllers/fileUploadController.js"></script>
<script src="../static/js/fileModel.js"></script>
Directives:
var app = angular.module('myApp', [])
app.directive("filesInput", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
Service
var app = angular.module('myApp', [])
app.factory('fileUploadService', function ($rootScope) {
var _files = [];
var service = {
add: add,
clear: clear,
upload: upload,
}
return service
function add(file){
_files.push(file)
$rootScope.$broadcast('fileAdded', file.files[0].name)
}
function clear(){
_files = []
}
function upload(){
_files.submit();
}
Controller:
var app = angular.module('myApp', [])
app.controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
$scope.$watch('uploadFile', function (newVal, oldVal) {
var submitBtn = document.getElementById('submitBtn');
//clear existing files
fileUploadService.clear()
if(newVal == true){
var formdata = new FormData();
$scope.getTheFiles = function ($files) {
angular.forEach($files, function (value, key) {
formdata.append(key, value);
});
};
// NOW UPLOAD THE FILES.
$scope.uploadFile = function () {
var request = {
method: 'POST',
url: file,
data: formdata,
headers: {
'Content-Type': undefined
}
};
// SEND THE FILES.
$http(request)
.success(function (d) {
alert(d);
})
.error(function () {
});
}
}]);
fileUploadService.add(newVal)
fileUploadService.upload()
}
})
By using this:
var app = angular.module('myApp', [])
it creates a new module, so controller, service and directive are registered in a separate module! This results in the injection error as controller cannot inject the service, as it is registered in a different module.
The solution is to only create one module and register all the other components in it, like this:
1st file:
var app = angular.module('myApp', []);
angular.module('myApp').factory('fileUploadService', function ($rootScope) {
...
});
2nd file
angular.module('myApp').controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
...
});
3rd file:
angular.module('myApp').directive("filesInput", function() {
...
});
Avoid multiple statements that create the module.
ERRONEOUS
var app = angular.module('myApp', [])
app.directive("filesInput", function() {
//...
});
var app = angular.module('myApp', [])
app.factory('fileUploadService', function ($rootScope) {
//...
}};
var app = angular.module('myApp', [])
app.controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
//...
});
The extra angular.module('myApp', []) statements are overwriting existing modules, resulting in the fileUploadService becoming unregistered.
BETTER
angular.module('myApp', [])
angular.module('myApp').directive("filesInput", function() {
//...
});
angular.module('myApp').factory('fileUploadService', function ($rootScope) {
//...
}};
angular.module('myApp').controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService){
//...
});
The statement creating the module must be placed before all the code adding more entities to it.
From the Docs:
Creation versus Retrieval
Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.
For more information, see
AngularJS Developer Guide - Modules - Creation versus Retrieval
AngularJS angular.module Function API Reference

AngularJS - Minifying modules with gulp

I am trying to set up a structure so I can minify/uglify all of my angular code.
I tried to copy the angular module structure from the Angle Bootstrap Theme
It works fine when all the unmified js files are loaded but when I try to minify all it ends up not finding the modules.
I am getting this error: [$injector:nomod] Module 'app.core' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
This is a MVC 5.2.3 project and the structure of the angular files are like this:
Scripts/angular/app.module.js
Scripts/angular/modules/core/core.config.js
Scripts/angular/modules/core/core.module.js
Scripts/angular/modules/module1/module1.controller.js
Scripts/angular/modules/module1/module1.module.js
So app.module.js looks like this:
(function() {
'use strict';
angular
.module('myApp', [
'app.core',
'app.module1',
...
]);
})();
core.config.js:
(function () {
'use strict';
angular
.module('app.core')
.config(coreConfig);
coreConfig.$inject = ['$controllerProvider', '$compileProvider', '$filterProvider', '$provide', '$animateProvider'];
function coreConfig($controllerProvider, $compileProvider, $filterProvider, $provide, $animateProvider) {
var core = angular.module('app.core');
core.controller = $controllerProvider.register;
core.directive = $compileProvider.directive;
core.filter = $filterProvider.register;
core.factory = $provide.factory;
core.service = $provide.service;
core.constant = $provide.constant;
core.value = $provide.value;
core.config(function (paginationTemplateProvider) {
paginationTemplateProvider.setPath(window.rootUrl + 'scripts/plugins/angular-pagination/dirPagination.tpl.html');
});
$animateProvider.classNameFilter(/^((?!(ng-no-animation)).)*$/);
}
})();
core.module.js:
(function() {
'use strict';
angular
.module('app.core', [
'ngSanitize',
'ngRoute',
'ngAnimate',
'ngResource',
'ngStorage',
'ui.bootstrap'
]);
})();
And all the modules have this structure:
module1.controller.js:
(function () {
'use strict';
angular
.module('app.note')
.controller('module1', module1);
module1.$inject = ['$scope', '$localStorage'];
function module1($scope, $localStorage) {
.....
};
})();
and the module1.module.js:
(function () {
'use strict';
angular
.module('app.module1', []);
})();
gulpfile.js
/// <binding Clean='clean' />
"use strict";
var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify");
var paths = {
webroot: "./"
};
paths.js = paths.webroot + "scripts/angular/**/*.js";
paths.minJs = paths.webroot + "scripts/angular/**/*.min.js";
..
gulp.task("min:js", function () {
return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});
..
probably is an order problem.
You have a good naming conventio so you can order your input stream taking the *.module.js files first.
you have to include
var order = require("gulp-order");
than after the gulp.src you have to order your input the risult should be likethis
gulp.task("min:js", function () {
return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
.pipe(order([
'**/*.module.js',
'**/*.js'
]))
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});
as you can see the order take an array of pattern.
Maybe the pattern are not perfect for your case but it should work.
hope this helps

Angular - DI dependency injection the connection between different Modules and service\directive from another module

If I need a to use a factory from another module do I need to add first the DI of the module to my current module and after that add the DI of the factory to the current factory? Or can I just add the factory itself (without its module)?
So if above its true the only use of Di in modules is for that use... or am i missing something else?
var myApp = angular.module('myApp', []);
myApp.service('myService', function() {
// do some stuff
});
myApp.controller('otherCtrl', function($scope, myService) {
// do some stuff
});
inject myApp module into otherApp module and use service myService:
var otherApp = angular.module('otherApp', ['myApp']);
otherApp.controller('myCtrl', function($scope, myService) {
$scope.myService = myService;
});
declare modules with dependecies.
var baseApp = angular.module("ERMSApp", ['ngSanitize', 'ngRoute', 'ngTable']);
var baseApp1 = angular.module("ERMSApp1", ['ERMSApp', 'ngSanitize', 'ngRoute', 'ngTable']);
declaring service.
baseApp.factory("getEmployeesService", function ($http) {
var promise;
var getEmployeesService = {
getEmployees: function () {
if (!promise) {
var promise = $http.get("/Timesheet/GetEmployees").then(function (result) {
return result;
});
}
return promise;
}
}
return getEmployeesService;
});
using service in another module
baseApp1.controller("leaveOnBehalfCtrl", function ($scope, $http, $filter, $sce, ngTableParams, $compile, getEmployeesService) {
getEmployeesService.getEmployees().then(function (data) {
$scope.employees = data.data;
})
});

Argument is not a function, got undefined with angular bootstrap, ui-router and requirejs

I am following Dan Wahlin's example of dynamically loading controllers using requirejs but with angular ui-router.
this is my app.js
var bootstrapper = angular.module('etrading', ['ui.router', 'ngSanitize','kendo.directives', 'common']);
function routeProvider($stateProvider, $controllerProvider, $compileProvider, $filterProvider, $provide, routeResolverProvider) {
$provide.decorator('$exceptionHandler', extendExceptionHandler);
bootstrapper.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
var route = routeResolverProvider.route();
$stateProvider.state('etrading', route.resolve('shell', 'core/', 'vm')).state('equityportfolio', route.resolve('equityportfolio', 'equityportfolio/', 'vm'));
}
bootstrapper.config([
'$stateProvider',
'$controllerProvider',
'$compileProvider',
'$filterProvider',
'$provide',
'routeResolverProvider',
routeProvider
]);
start.$inject = ['$state', '$rootScope', '$q', 'genXClientFactory'];
function start($state, $rootScope, $q) {
//set the initial state
$state.go('etrading');
}
bootstrapper.run(start);
this is my main.js for angular bootstrap
define([
'app',
'common/common',
'common/routeresolver',
'common/logger',
'common/commonfactory',
'common/spinner',
'common/genxInitializer',
'common/route'
],
function () {
angular.element(document).ready(function () {
angular.bootstrap(document, ['etrading']);
});
});
this is my routeresolver.route method
var route = function () {
function resolve(baseName, path, controllerAs, secure) {
if (!path)
path = '';
var routeDef = {};
var baseFileName = baseName.charAt(0).toLowerCase() + baseName.substr(1);
routeDef.templateUrl = viewsDirectory + path + 'views/' + baseFileName + '.html';
routeDef.controller = baseName + 'Controller';
if (controllerAs)
routeDef.controllerAs = controllerAs;
routeDef.secure = (secure) ? secure : false;
routeDef.resolve = {
load: [
'$q',
'$rootScope',
function ($q, $rootScope) {
var dependencies = [controllersDirectory + path + 'controllers/' + baseFileName + 'Controller.js'];
return resolveDependencies($q, $rootScope, dependencies);
}
]
};
return routeDef;
}
function resolveDependencies($q, $rootScope, dependencies) {
var defer = $q.defer();
require(dependencies, function () {
defer.resolve();
$rootScope.$apply();
});
return defer.promise;
}
var jsclass = {
resolve: resolve
};
return jsclass;
};
and this is the controller that i am trying to register
define(["require", "exports", 'app'], function (require, exports, app) {
var core;
(function (core) {
var controller;
(function (controller) {
var Shell = (function () {
function Shell($rootScope, common, config) {
}
Shell.$inject = ['$rootScope', 'common', 'config'];
return Shell;
})();
controller.Shell = Shell;
app.etrading.register.controller('shell', Shell);
})(controller = core.controller || (core.controller = {}));
})(core = exports.core || (exports.core = {}));
});
I am getting this: Error: [ng:areq] Argument 'shellController' is not a function, got undefined this is when trying to resolve the dependencies. Please help me with this.
Thanks.
Figured out that after ui-router's routesuccess it check if the controller name is same as controller defined in the state change.
controller name has to be
app.etrading.register.controller('shellController', Shell);
and not app.etrading.register.controller('shell', Shell);

Controller and services are not loading in angularjs

I have integrated requirejs with my angular app.
But while loading app, it gives me an error 'Argument 'appCtrl' is not a function, got undefined'
Here is my controller code :
define(['Angular'], function (angular) {
function appCtrl($scope, pathServices) {
alert('sa');
}
function homeCtrl($scope, brandService) {
console.log('dfd');
}
});
And along with this, it gives error for 'unknown provider pathServices'
Service code is :
serviceConfig.js
define([
'Angular',
'common/Services/services',
'current/js/services'
], function(angular, commonServices, loacalStorageServices, currentServices) {
"use strict";
var services = {
commonServices : commonServices,
currentServices : currentServices,
};
var initialize = function (angModule) {
angular.forEach(services,function(service, name) {
angModule.service(name, service);
});
}
return {
initialize: initialize
};
});
common/services.js
define(['Angular'], function (angular) {
var app = angular.module('myApp.services', []);
app.factory('pathServices', function($http, $q, $rootScope) {
function pathServices() {
alert('as');
}
return new pathServices();
});
app.factory('anotherServices', function($http, $q, $rootScope) {
function anotherServices() {
alert('as');
}
return new anotherServices();
});
});
current/services.js
define(['Angular'], function(angular) {
var app = angular.module('myApp.services', []);
app.factory('brandsService', function() {
function brandsService() {
var autoCompleteData = [];
this.getSource = function() {
return autoCompleteData;
}
this.setSource = function(states) {
autoCompleteData = states;
}
}
return new brandsService();
});
});
in serviceConfig.js I have included 2 service files.. But the problem is, the last current/service.js file overwrites all files.. How can I include multiple service files ?
I am new to requirejs. How can I use controller function and services using requirejs ?
Can anyone help ?
You have to declare your functions in the global (window) namespace, or register them in your module with the moduleName.controller('controllerName',controllerFn)
So either
define(['Angular'], function (angular) {
window.appCtrl = function($scope, pathServices) {
alert('sa');
}
window.homeCtrl = function($scope, brandService) {
console.log('dfd');
}
});
or
define(['Angular'], function (angular) {
var module = angular.module('theModuleName');
module.controller('appCtrl', function($scope, pathServices) {
alert('sa');
});
module.controller('homeCtrl', function($scope, brandService) {
console.log('dfd');
}
});
should fix this error (I prefer the second approach).

Resources