I am trying to pass variable to angular js config,
This is my js app:
var app = angular.module('myApp', ['ngMaterial', 'sasrio.angular-material-sidenav', 'ui.router']);
app.controller('baseController', function ($scope, $mdDialog, $mdMedia, $http, $rootScope, $timeout, $mdToast, $mdSidenav, ssSideNav) {
$scope.menu = ssSideNav;
$scope.getRequirment = function () {
$http.get("site/requirment",
{params: {dir: $scope.currentPath}})
.then(function (response) {
return response.data;
});
};
$scope.getRequirment();
});
app.config(['$mdThemingProvider', '$locationProvider', 'ssSideNavSectionsProvider', '$stateProvider',
function ($mdThemingProvider, $locationProvider, ssSideNavSectionsProvider, $stateProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('deep-orange')
.accentPalette('deep-orange');
ssSideNavSectionsProvider.initWithTheme($mdThemingProvider);
ssSideNavSectionsProvider.initWithSections("Get getRequirment function in controller");
}]);
How can I call a function in the controller from config?
I mean this line:
ssSideNavSectionsProvider.initWithSections("Get getRequirment function in controller");
There is a durty way to do this:
you can put this in your config
$rootScope.$watch("variable", function(n, o) {
// assign n value
})
and in your controller just set the
$rootScope.variable
It's impossible, controller executes in run phase, config in config phase.
I investigate source code a little, sections available as a service variable, you could try to add them from controller:
ssSideNavSections.sections.push(yourSection);
You can set constant in configuration block and then access that constant via injecting it into controller.
Source: https://www.agiliq.com/blog/2017/04/what-when-and-how-angularjs-configuration-blocks/
Related
Hi I've been trying to unit test basic functions in my controller however I can't seem to connect when setting up the unit test.
Error: [$injector:modulerr] Failed to instantiate module myApp due to:
[$injector:nomod] Module 'myApp' 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.
Here is my controller:
var myApp = angular.module("myApp", []);
myApp.controller('studentController', function($scope,$route,$routeParams,$http,$location){
//Get all students
$scope.getStudents = function(){
$http.get('/api/student/').then(function(response){
$scope.students = response.data;
});
};
and my test:
describe("studentController", function () {
beforeEach(module('myApp'));
var $controller;
beforeEach(inject(function (_$controller_){
$controller = _$controller_;
}))
describe("studentController", function(){
it("should get student data", function (){
var $scope = {};
$scope.getStudents();
expect($scope.students.length).toBe(15)
})
})
});
I have included both these files in the jasmine html file along with the angular-mocks.js
any help would be much appreciated
You are injecting $route, but you are not loading the ngRoute module. Load the file angular-route.js and state the dependency:
var myApp = angular.module("myApp", ['ngRoute']);
You have to create controller in before each by using following and as you are calling getStudents that shuold be mocked by using HttpBackend service in unit test.
Controller
var myApp = angular.module("myApp", []);
myApp.controller('studentController', function($scope, $route, $routeParams, $http, $location) {
//Get all students
$scope.getStudents = function() {
$http.get('/api/student/').then(function(response) {
$scope.students = response.data;
});
};
});
Test file
describe("studentController", function() {
beforeEach(module('myApp'));
var $controller, scope, route;
beforeEach(inject(function(_$controller_, $rootScope, $route, $routeParams, $http, $location) {
$controller = _$controller_;
scope = $rootScope.$new();
$controller('studentController', {
'$scope': scope,
'$route': $route,
'$routeParams': $routeParams,
'$http': $http,
'$location': $location
});
}))
describe("studentController", function() {
it("should get student data", function() {
// for this you have to use httpBackend
// you have to mock the response of api
$scope.getStudents();
// then you are able to verify the result in student
expect($scope.students.length).toBe(15)
})
})
});
For more information you can refer unit testing and Httpbackend
Here is my controller:
(function () {
var app= angular.module('app');
app.controller('recommendedJobsCtrl', ['$scope', function(dataShare,$q,$scope, $ionicSideMenuDelegate,$window,$http,$timeout) {
// passes contents to jobDetails to be rendered and displayed
window.post = function($event, res){
console.log(angular.element($event.target).parent());
dataShare.sendData(res)
}
/**
* handles pagination
*loads first 3 pages
**/
var i=1;
window.result=[];
window.noMoreItemsAvailable=false;
window.loadMore = function()
{
console.log('here')
if(i<4)
{
$http.get( "http://test.website.com/api/search/"+i).success(function(response)
{
i++;
$scope.result=$scope.result.push(response);
console.log(response);
$timeout(function ()
{
$scope.result = response
});
$scope.$broadcast('scroll.infiniteScrollComplete');
});
}else
{
$scope.noMoreItemsAvailable=true;
}
}
]);
}());
I read that my controller was under 'user strict' so it can't access the variables or functions. So I placed the word 'window' to make it global. But now it doesn't access the function because the console won't print. How do I fix this?
Dependency Injection is incorrect:
app.controller('recommendedJobsCtrl', [
'dataShare',
'$q',
'$scope',
'$ionicSideMenuDelegate',
'$window',
'$http',
'$timeout',
function(
dataShare,
$q,
$scope,
$ionicSideMenuDelegate,
$window,
$http,
$timeout) {
// Your code ...
}]);
Your code should be specific to the controller. You should create function and variables either on $scope as in $scope.<functionName> = function() {} and $scope.noMoreItemsAvailable or private to the controller as in function <functionName>() {} or var noMoreItemsAvailable.
In case intention behind using window object is to use same code across controllers, you may put this code in a factory.
I have declared my app and have one controller (for demonstration purposes):
var module = angular.module("app", [])
module.controller("modalCtrl", ["$scope", function ($scope, dataService) {
$scope.printEntity = function () {
console.log(dataService.getEntityArray());
}
}]);
And a service:
module.factory("dataService", function () {
var entityArrayService = [1,2];
return {
getEntityArray: function () {
return entityArrayService;
}
};
});
When I call $scope.printEntity from my view, I'm always told dataService.getEntityArray() is undefined.
I've loaded the service as a dependency and declared my entityArrayService array outside of my return statement. I've looked high and low for an answer but to no avail. My goal is to share a piece of data between two controllers, but at the minute I can't even use one controller to retrieve data.
The service isn't loaded as a dependency. Change this line:
module.controller("modalCtrl", ["$scope", function ($scope, dataService) {
to this:
module.controller("modalCtrl", ["$scope", "dataService", function ($scope, dataService) {
You are using strict syntax for dependencies declaration. So if you add a parameter to your controller, you must add its declaration too.
module.controller("modalCtrl", ["$scope", "dataService", function ($scope, dataService) {
...
}
You didn't inject dataService in your controller. Try with:
module.controller("modalCtrl", ["$scope", "dataService", function ($scope, dataService) {
// ...
});
The injection of the service in the controller is missing:
please correct to:
...
module.controller("modalCtrl", ["$scope", "dataService", function ($scope, dataService) {
...
The other code is correct.
I'm injecting controller from external file and I want to do the same thing for the service from external file. It should be registered in factory statement.
Injecting of the controller working
controllers
'use strict';
define(['angular', 'services'], function (angular) {
return angular.module('vcApp.controllers', ['vcApp.services'])
.controller('AuthCtrl', ['$scope', '$injector','AuthService', function($scope, $injector, AuthService) {
require(['auth/authCtrl'], function(authCtrl) {
$injector.invoke(authCtrl, this, {'$scope': $scope, 'AuthService':AuthService});
});
}]);
});
authCtrl
define([], function() {
return ['$scope', '$routeParams', '$location', '$http', 'AuthService', function($scope, $routeParams, $location, $http, authService) {
$scope.signIn = function() {
...
}
$scope.$apply();
}];
});
And now I want to inject service
services
'use strict';
define(['angular'], function (angular) {
angular.module('vcApp.services', [])
.factory('AuthService', ['$http', '$injector', function($http, $injector) {
require(['auth/authService'], function(authService) {
$injector.invoke(authService, this, {'$http': $http});
});
}]);
});
authService
define([], function() {
return ['$http', function ($http) {
return {
login: login
};
function login(username, password) {
var request = $http(...);
return(request);
}
}]
});
When authController calls authService.login(...), it throws error Error: [$injector:undef] Provider 'AuthService' must return a value from $get factory method..
This code was inspired by angular-requirejs-seed project.
As it says, Angular's factory() is expected to return the service object. You may have luck with something like:
define(['angular'], function (angular) {
angular.module('vcApp.services', [])
.factory('AuthService', ['$http', '$injector', function($http, $injector) {
var stub = {};
require(['auth/authService'], function(authService) {
angular.extend(stub, $injector.invoke(authService, this, {'$http': $http}));
});
return stub;
}]);
});
Here you define a stub for the service and extend it, when the service is actually lazy-loaded.
(By the way I think the last 2 arguments of $injector.invoke() are redundant in this case.)
If you want another idea about mixing RequireJS and Angular, that plays well with lazy loading and the r.js optimizer, you may take a look at angular-require-lazy.
I have the following url:
http://myurl.dev/users/32
I want to pass the last parameter 32 to a $http.get request but I can't figure out how to pass it.
So far I have this:
var matchmaker = angular.module('matchmaker', ['ngRoute'], function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
})
.controller('LocationCtrl', ['$scope', '$http', '$location', '$routeParams', '$route', function($scope, $http, $location, $routeParams, $route) {
var id = $route.current.params.id;
console.log(id);
$http.get('http://myurl.dev/services/' + id ).success(function(data)
{
$scope.applicants = data;
});
}]);
In the console it's saying:
Cannot read property 'params' of undefined
Can anyone tell me what I'm doing wrong please?
Edit:
Angular isn't generating the url, it's a server side generated url
Edit 2.0
Here's the config for the routeProvider with actual route parameters:
var matchmaker = angular.module('matchmaker', ['ngRoute'], function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
})
.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/matchmaker/locations/:id', {
controller: 'LocationCtrl'
});
$locationProvider.html5Mode(true);
});
Put a console.log($routeParams); in your controller and check its value.
If it is Object {} check if you have a route definition using parameters:
var module = angular.module('ngRouteExample', ['ngRoute']);
module.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/test/:id', {
templateUrl: 'test.html',
controller: 'TestController'
});
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
});
If so, you will get this output in the console:
Object {id: "42"}
It is because you trying to get value which doesn't exist at that moment, that's how javascript works. You need to specify that you want these values when they are ready using '$routeChangeSuccess' event.
.controller('PagesCtrl', function ($rootScope, $scope, $routeParams, $route) {
//If you want to use URL attributes before the website is loaded
$rootScope.$on('$routeChangeSuccess', function () {
//You can use your url params here
$http.get('http://myurl.dev/services/' + $routeParams.id )
.success(function(data) {
$scope.applicants = data;
});
});
});