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.
Related
This line of code does no let me sleep:
$scope.search = function (login) {
github.getUser(login).then(onUserResponse, onError);
};
Loading it up:
angular.module('lol')
.factory('github', github);
Returning two functions :
return {
getUser: getUser,
getRepos: getRepos
};
With this siganture:
var github = function ($http) {
Consumed by MainController:
var MainCtrl = function ($scope, github, $filter, $timeout, $intervel, $anchorScroll, $location) {
And not injected into it's dependencies:
MainCtrl.$inject = ['$scope', '$filter', '$interval', '$timeout', '$anchorScroll', '$location'];
With the app being loaded like this:
angular.module('lol', [])
.controller('MainCtrl', MainCtrl);
And all of this throw: TypeError: __tracer.traceFunCall(...) is not a function
i think you missed githubas second parameter in MainCtrl.$inject = ['$scope', 'github'...
also updated your jsbin here
code organization was complicating situation more than necesary.
Also from the looks of it you tried to do two modules quick example how it should be done here.
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 created custom service
(function () {
"use strict";
angular
.module("common.services")
.factory("redirectService",
["$q", "$location",
redirectService])
.config(function ($httpProvider) {
$httpProvider.interceptors.push('redirectService');
});
function redirectService($q, $location){
...
var redirect = function() {
...
};
return {
doRedirect: redirect
};
}
inside my other controller where I'm injecting this redirectService I'm trying to call this publish doRedirect method
angular
.module("myModule")
.controller("MyController",
["$scope",
"redirectService"
MyController]);
function MyController(redirectService){
vm.doClick = function() {
redirectService.doRedirect();
}
}
Here I'm getting error on calling doRedirect method
Error: redirectService.doRedirect is not a function
You have an imbalance of number of arguments in dependency array and function arguments for MyController
Change
function MyController(redirectService){
To
function MyController($scope, redirectService){
MyController function has two arguments first $scope, second redirectService
angular
.module("myModule")
.controller("MyController",
["$scope",
"redirectService"
MyController]);
function MyController($scope, redirectService){
vm.doClick = function() {
redirectService.doRedirect();
}
}
Can you help me please?
I want to set controller name which contains in scope of another controller.
JS file:
.controller('PageCtrl', [
'$http',
'$scope',
'$routeParams',
'$location',
function($http, $scope, $routeParams, $location){
switch($routeParams.page) {
case 'companies':
$scope.CurrentPageCtrl = 'CompaniesCtrl';
break;
default:
break;
}
}])
.directive('myPagecontent', function() {
return {
template: '<ng-controller ng-controller = "{{CurrentPageCtrl}}"></ng-controller>'
};
})
HTML file:
<ng-controller ng-controller = "PageCtrl">
<my-pagecontent></my-pagecontent>
</ng-controller>
And I get error:
angular.js:13642 Error: [ng:areq] Argument '{{CurrentPageCtrl}}' is not a function, got undefined
This can be a bit tricky since ng-controller in this case expects an expression that evaluates to a controller constructor function, not to a string that contains the controller name.
One way to solve it is by doing the following:
app.controller('PageCtrl', [
'$http',
'$scope',
'$location',
function($http, $scope, $location) {
$scope.CurrentPageCtrl = Controller1;
}
]);
function Controller1($scope) {
console.log('Controller1');
}
app.controller('Controller1', Controller1);
function Controller2($scope) {
console.log('Controller2');
}
app.controller('Controller2', Controller2);
app.directive('myPagecontent', function() {
return {
template: '<ng-controller ng-controller="CurrentPageCtrl"></ng-controller>'
};
});
Demo: http://plnkr.co/edit/s3yy2fdF5OgBjPcKWikw?p=preview
An alternative solution is to create a directive that runs before everything else, that takes a variable with the controller name, adds ng-controller with the correct value and then remove itselves.
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.