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);
}
])
Related
How do I pass the resolve validToken value to my controller?
Config:
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/recover/:token', {
templateUrl: 'recover.html',
controller: 'recoverCtrl',
resolve: {
validToken : function(){
return "INVALID TOKEN"
}
}
});
}])
Controller:
.controller('recoverCtrl', ['$location','$scope','$http', '$routeParams', '$rootScope',
function($location,$scope,$http,$routeParams,$rootScope,validToken) {
console.log(validToken);
// Rest of controller code.
}
]);
I would like to do this without removing the []'s so the code could eventually be minifed. The below example is working as I expected so I know that all of my code it working, I'm just not sure what I should add to the above code to make it function similarly.
.controller('recoverCtrl', function($location,$scope,$http,$routeParams,$rootScope,validToken) {
console.log(validToken);
//Other code
});
Figured it out thanks to Etsus.
I just needed to add the object key as a string while injecting and it was able to determine that it was a resolve key
.controller('recoverCtrl', ['$location','$scope','$http', '$routeParams', '$rootScope', 'validToken', function ($location, $scope, $http, $routeParams, rootScope, validToken) {
console.log(validToken);
}]);
In a $stateProvider state I want to:
Load a service JS file
Resolve a service function (API call)
Pass resulting data to controller
controllers/my-controller.js
angular.module('app').
controller('MyController', ['$scope', function($scope, serviceData){
console.log(serviceData)
}]);
config.js
...
.state('main', {
url: "/",
templateUrl: 'templates/my-template.html',
controller: 'MyController',
resolve: {
dependencies: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
'controllers/my-controller.js'
])
}],
serviceData: ['$ocLazyLoad', '$injector', function($ocLazyLoad, $injector) {
return $ocLazyLoad.load('services/my-service.js')
.then(function(){
var $myService = $injector.get('MyService');
return $myService.GetData();
})
}]
}
})
I would expect the controller to console.log the data coming back from the API call that MyService does (not included for brevity, but that part works). Instead, I get undefined.
Any ideas?
Thanks!
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;
});
});
});
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
}
}]);
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) {
}];