I'd like to display my template when the data coming from my server are loaded.
I created a module called Services with inside some services to load my data, I'm using HomeService for my example.
var app = angular.module('MyApp', ['Services']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: 'home.html',
controller: 'Home_Ctrl',
resolve: {
loadData: //??
}
});
}]);
app.controller('Home_Ctrl', ['$scope', 'HomeService', function($scope, HomeService) {
$scope.data = HomeService.getData();
}
I guess I need to create a promise to do that. Is it possible to put this function inside my controller?
I mean, I don't want something like that:
var ctrl = app.controller('Home_Ctrl', ['$scope', 'HomeService', function($scope, HomeService) {
//Do something
}
//Promise
ctrl.fct = function($q) {
}
I want something like that:
app.controller('Home_Ctrl', ['$scope', '$q', 'HomeService', function($scope, $q, HomeService) {
//Do something
//Promise
this.fct = function() {}
}
Any idea?
Thanks.
You could use resolve property of controller.
You could create a object which will return promise and assign to controller resolve function and inject the same in controller definition kindly see very simple example
$routeProvider.when('/ExitPoll', {
templateUrl: '/partials/ExitPoll.html', controller: exitpollController, resolve: {
responseData: ['$http', function ($http) {
return $http.get('/Candidate/GetExitPolls/hissar').then(function (response) {
return response.data;
});
}],
}
});
var exitpollController = ['$scope', '$http','responseData','$rootScope',
function ($scope, $http, responseData, $rootScope) {
}];
Related
So I have a problem with angular ui.router, which apparently isn't passing the data from resolve to controller. I have the following state set up:
$stateProvider
.state('myState', {
url: "/myUrl",
templateUrl: "myTemplate",
controller: 'myController',
resolve: {
randomData: function($q, $sails) {
var defer = $q.defer();
$sails.get("/me")
.success(function(data) {
console.log(data) // prints out actual data
defer.resolve(data);
})
return defer.promise;
}
}
and in myController I basically have
myApp.controller('myController', [
'$scope', function ($scope, randomData) {
console.log("randomData:" + randomData)
// prints out 'randomData: undefined'
}
])
According to every doc, stackoverflow post and tutorial, this piece of code should work, but it keeps printing undefined. Does anyone have an idea why this isn't working?
You forgot to inject the data in the array notation:
myApp.controller('myController', [
'$scope', 'randomData', // <-- this one
function ($scope, randomData) {
console.log("randomData:" + randomData);
}
])
I have created a directive inside my controller, which i want to include another controller to the directive. The error i get back is Error: [ng:areq] Argument 'js/controllers/testview/DocumentController.js' is not a function, got undefined
TestviewController
app.controller('TestviewController', ['$http', '$scope', '$sessionStorage', '$state', '$log', 'Session', 'api', function ($http, $scope, $sessionStorage, $state, $log, Session, api) {
var module_id = $state.params.id;
$http.get(api.getUrl('componentsByModule', module_id))
.success(function (response) {
$scope.components = response;
});
}]);
app.directive('viewDoc', function () {
return {
templateUrl: "tpl/directives/testview/document.html",
controller: "js/controllers/testview/DocumentController.js",
resolve: { components: function() { return $scope.components }}
};
});
DocumentController
app.controller('DocumentController', ['$http', '$scope', '$sessionStorage', '$state', '$log', 'Session', 'api', 'components', function ($http, $scope, $sessionStorage, $state, $log, Session, api, components) {
$scope.components = components;
}]);
I'm pretty new with directices, but does anyone have any idea what I'm doing wrong?
Inside the directive definition object, the controller property expects a string with the function name, or the function itself (not the path to script file).
app.directive('viewDoc', function () {
return {
...
controller: "DocumentController",
};
});
You want to call the controller by name, not by file name:
controller: "js/controllers/testview/DocumentController.js"
should be
controller: "DocumentController"
There is no option to put controller by its URL in the directive definition. However if you define your controller in DOM template you could use controller: 'myController as myCtrl' in directive definition
are you sure you need a directive controller? i think what you are trying to achieve is link function.
you can use directive link functions like controllers.
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html',
link: function (scope, element) {
scope.name = 'Jeff';
}
};
});
take a look at angular docs
https://docs.angularjs.org/guide/directive
I am trying to create some routing that will resolve calls to my rest api
before the page loads. Because I can't inject a service created using
app.factory(), I am attempting to create a provider to do this so I can use it in my config routing, but I'm
getting Error: [$injector:unpr] Unknown provider: $http
I want to be able to call the provider in mainFlow.api for 4 or five endpoints
that will resolve before the page loads. Am I going about this the correct way?
My code:
service.js
var mainApp = angular.module('mainApp');
mainApp.provider('choiceService', ['$http', function($http) {
return {
$get: function() {
return {
get: function(url) {
return $http.get(url);
}
};
}
};
}]);
config.js
var mainApp = angular.module('mainApp', [
'ui.router'
]);
mainApp.config(['$stateProvider', '$urlRouterProvider', '$choiceServiceProvider',
function($stateProvider, $urlRouterProvider, choiceServiceProvider) {
$stateProvider
.state('mainFlow', {
abstract: true,
url: '/base',
template: '<ui-view/>'
})
.state('mainFlow.choose-main', {
url: '',
templateUrl: '/choose_main.html',
})
.state('mainFlow.contact', {
controller: 'ContactFormController',
url: '/contact-details',
templateUrl: '/panel_contact_info.html',
})
.state('mainFlow.api', {
url: '/about-your-api',
controller: 'ApiFormController',
templateUrl: '/panel_about_your_api.html',
resolve: {
choice: function(choiceServiceProvider) {
return choiceServiceProvider.get('/api/yes-no-choice/');
},
other_choice: function(choiceServiceProvider){
return choiceServiceProvider.get('/api/my-other-choice/')
}
}
})
Then I can use the resolved data in controller.js
controller.js
var mainApp = angular.module('mainApp');
mainApp.controller('ApiFormController', [
'$scope',
'$state',
'choiceService',
function($scope, $state, choiceService) {
$scope.choices = choiceService;
}
]);
I was passing $http in service.js when there was no need. I was also passing in '$choiceServiceProvider' in config.js when it should have been just 'choiceServiceProvider'
I'm having problems finding the solution to TypeError: undefined is not a function in my code.
I have the following app.js:
var app = angular.module('test', ['ngRoute', 'test.services', 'test.directives', 'test.controllers']);
app.config(function ($routeProvider, $httpProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/q/:q', {
templateUrl: '/templates/productlist.html',
controller: 'ProductCtrl'
}).
otherwise({
redirectTo: '/q'
});
});
Then I have a controller
var controllers = angular.module('test.controllers', []);
controllers.controller('ProductCtrl', ['$scope', '$routeParams', 'ProductFactory',
function ($scope, ProductFactory, $routeParams) {
$scope.query = $routeParams.q;
$scope.products = ProductFactory.query({query: $scope.query});
}]);
And a factory
var services = angular.module('test.services', ['ngResource']);
var baseUrl = 'http://localhost\\:8080';
services.factory('ProductFactory', function ($resource) {
return $resource(baseUrl + '/test/smart/:query', {}, {
query: { method: 'GET', isArray: true }
})
});
This code results on load in the above mentioned TypeError on the line $scope.products = ProductFactory.query({query: $scope.query}); in my controller.
Further, when debugging my code I see that $routeParams.q is null or undefined.
What I want is that in my controller the $scope.products variable becomes an array with the result of the query.
What am I doing wrong?
Please try with correct function arguments,
controllers.controller('ProductCtrl', ['$scope', '$routeParams', 'ProductFactory',
function ($scope /*ProductFactory*/, $routeParams, ProductFactory) {
$scope.query = $routeParams.q;
$scope.products = ProductFactory.query({query: $scope.query});
}]);
I have 2 routes that share a controller, one needs data resolved prior to the view loading, and the other does not need the resolved data.
Routing segment example:
...
when('/users', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/view.html',
resolve: {
resolvedData : ['Accounts', function(Accounts) {
return Accounts.get();
}]
}
}).
when('/users/add', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/add.html'
})
...
Controller example:
app.controller('UsersCtrl', ['$scope', 'Helper', 'resolvedData',
function($scope, Helper, resolvedData) {
// this works for the first route, but fails for the second route with
// unknown "resolvedDataProvider"
console.log(resolvedData);
}]);
Is there any way I can get the resolvedData in the controller without explicitly using the resolve name as a dependency? So a check can be performed?
Using the $injector does not work. I would like to do something similar to:
if ($injector.has('resolveData')) {
var resolveData = $injector.get('resolveData');
}
However this does not work even for the route that has the resolveData set ('/users'):
app.controller('UsersCtrl', ['$scope', 'Helper', '$injector',
function($scope, Helper, $injector) {
// this does not work -> fails with the unknown "resolvedDataProvider" as well
$injector.get('resolvedData');
}]);
Can this be done in angularjs? Or should I just create a new controller?
Thank you.
Looks like I figured out another way to go. The resolved data is part of the $route. So you can access it using:
app.controller('UsersCtrl', ['$scope', '$route', 'Helper',
function($scope, $route, Helper) {
if ($route.current.locals.resolvedData) {
var resolvedData = $route.current.locals.resolvedData;
}
}]);
If the other route doesn't need it, just inject undefined on that route:
router:
when('/users', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/view.html',
resolve: {
resolvedData : ['Accounts', function(Accounts) {
return Accounts.get();
}]
}
}).
when('/users/add', {
controller: 'UsersCtrl',
templateUrl: '/partials/users/add.html',
resolve: {
resolvedData: function() {
return undefined;
}
}
})
controller:
app.controller('UsersCtrl', ['$scope', 'Helper', 'resolvedData',
function($scope, Helper, resolvedData) {
if(resolvedData){
//set some scope stuff for it
} else {
//do what you do when there is no resolvedData
}
}]);