$routeProvider resolve is not getting object from promise - angularjs

I am having trouble trying to get an array of objects from a promise. I have two issues. First, when the GetAccounts() gets called in the AccountService, it returns 2 objects. In the resolve, when I check the variable result, it doesn't have the 2 objects. Second, when the controller gets instantiated, it gives me this error: accounts is not defined. Can anyone tell me what I am doing wrong? Thanks in advance.
AccountService.js
app.factory('AccountService', ['$http', function ($http) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function success(response) {
return response.data;
}, function error(response) {
return console.log("Oops!");
});
}
};
}]);
AdminController.js
app.component('admin', {
templateUrl: 'Content/app/components/admin/Admin.html',
bindings: {
accounts: '<'
},
controller: function () {
this.accounts = accounts;
}
})
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/admin', {
template: '<admin accounts="$resolve.GetAccounts"></admin>',
resolve: {
GetAccounts: ['AccountService', function (AccountService) {
var result = AccountService.GetAccounts();
return result;
}]
}
})
}]);

Make the following changes to get it works.
AdminController.js
app.component('admin', {
templateUrl: 'Content/app/components/admin/Admin.html',
bindings: {
accounts: '<'
} })
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/admin', {
template: 'template.html',
resolve: {
GetAccounts: ['AccountService', function (AccountService) {
var result = AccountService.GetAccounts();
return result;
}]
},
controller:['$scope','GetAccounts',function($scope, GetAccounts){
$scope.accounts = GetAccounts;
}]
})
}]);
template.html
<div>
<admin accounts="accounts"></admin>
</div>

Related

in Angular, passing a value from resolve to the controller

I am trying to pass this variable to the controller and then display on the screen. I am not sure why I am getting undefined for that value. I went tru the similar SO questions and it seems iam doing it right.
.state({
name: "test",
url: "/testURL",
views: {
'testView': {
template: '<div><span>{{testvariable}} </span></div>',
controller: "testController",
resolve: {
testString: function () {
debugger;
return 'from Resolve';
}
}
}
},
})
})
app.controller("testController", ["$scope", "$state",
function ($scope, $state, testString) {
console.log("getting from resolve ", testString)
$scope.testvariable = function () {
console.log("getting from resolve ", testString)
return testString;
}
$scope.testvariable();
}
])

Angular 1.5 Unknown provider

So i get the:
Error: $injector:unpr
Unknown Provider
Unknown provider: canOrganiseProvider <-
i cannot figure out why, i simple have this end point which i've tested it works ok, and just want to resolve this before i navigate to a route, it does not work when trying to resolve canOrganise, any ideas why?
Thank you.
Jumping into code.
The end point.
[HttpGet]
[Route("{eventCode}/isOrganiser")]
[Audit(AuditLog.Nothing)]
public IHttpActionResult HasOrganisationalRights([FromUri] string eventCode)
{
var response = Resolve<ICanManageEventOrganisationRightsOperation>().CanOrganiseEvent(new CanManageEventOrganisationRequest
{
EventCode = eventCode,
CurrentUser = CurrentUser,
});
return CreateResponse(response, () => response.CanOrganise );
}
Angular routing:
angular.module('Events').config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/event/:event/attendees', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendees($route.current.params.event).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return false;
}]
}
})
}
]);
Angular service
angular.module('Events').factory('AttendeesService', ['$http',
function ($http) {
return {
getAttendee: function (eventCode, accountName) {
return $http.get('api/events/' + eventCode + '/attendees/' + accountName + '/');
},
isOrganiser: function (eventCode) {
return $http.get('api/events/' + eventCode + '/isOrganiser');
},
}
Angular controller
angular.module('Events').controller('AttendeesController', ['$scope', '$rootScope', '$routeParams', '$location', '$filter', 'data', 'canManage', 'canOrganise',
'grouped', 'AttendeesService', 'AttendeeAdderService', 'AttendeeDeleterService', 'TrackingService', 'WatcherAdderService', 'WatcherDeleterService',
'GroupColorChangerService', 'DefaultSortingChangerService', 'AdminService',
function ($scope, $rootScope, $routeParams, $location, $filter, data, canManage, canOrganise, grouped, AttendeesService, AttendeeAdderService, AttendeeDeleterService,
TrackingService, WatcherAdderService, WatcherDeleterService, GroupColorChangerService, DefaultSortingChangerService, AdminService) {
...
$scope.isOrganiser = canOrganise;
...
}
]);
angular.module('Events', [
'ngRoute', 'ngSanitize',
'angularModalService', 'ngTagsInput'
]);
found my issue, in the routing.js file i have another route that points to same controller but different URL . did not noticed the 1st time .. so adding the provider to the correct route solved my problem.
added it here
.when('/event/:event/attendees', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendees($route.current.params.event).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return false;
}]
}
})
but should have added it here
.when('/event/:event/attendees/grouped/:fieldId', {
templateUrl: '/Content/AngularApp/Attendees/List/Template.html',
controller: 'AttendeesController',
resolve: {
'data': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.getAttendeesGrouped($route.current.params.event, $route.current.params.fieldId).then(function (response) {
return response.data;
});
}],
'canManage': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.canManage($route.current.params.event).then(function (response) {
return response;
});
}],
'canOrganise': ['$route', 'AttendeesService', function ($route, AttendeesService) {
return AttendeesService.isOrganiser($route.current.params.event).then(function (response) {
return response;
});
}],
'grouped': function () { return true; },
}
})
For use $routeProvider you mast include ng-route module to your app module:
angular.module('yourModule', ['ngRoute'])
and add connect script in your html file:
<script src="bower_components/angular/angular.min.js"></script>
...
<script src="bower_components/angular-route/angular-route.min.js"></script>

Object doesn't support property or method 'query' in angular

Factory
(function () {
angular.module("common.script").factory("expenseResource", ["$resource", expenseResource]);
function expenseResource($resource) {
var expenceCategory = function ($resource) {
return $resource("api/expenceCategory/:expenceCategoryId");
}
return {
expenceCategory: expenceCategory
};
}
})();
Controller
(function () {
var app = angular.module("ExpenceManagerApp", ["ui.router", "common.script", "expenseResourceMock"]);
app.config(["$stateProvider","$urlRouterProvider", function ($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state("HomePage", {
url:"/",
templateUrl: "App/Main/homePage.html",
})
.state("Settings", {
url: "/Settings",
templateUrl: "App/Expense/settingsPage.html",
})
.state("expenceCategoryEdit", {
url: "/expenceCategoryEdit",
templateUrl: "App/Expense/editExpenseCategory.html",
controller: "editExpenseCategoryCtrl as vm",
resolve: {
expenseResource: "expenseResource",
expenseCategoryList: function (expenseResource) {
return expenseResource.expenceCategory.query().$promise;
}
}
})
}]);
}());
expenceCategory is a function, so use it as function:
expenseResource.expenceCategory().query().$promise
OR define expenceCategory as field:
return {
expenceCategory: expenceCategory()
};
NB: your service creates new $resource each time it is launched. It should be just:
function expenseResource($resource) {
return $resource("api/expenceCategory/:expenceCategoryId");
}
And in controller:
expenseResource.query().$promise

Why can't i use the $http service in a route resolve?

I want to make my views show only after the initial data is fetched and i am trying to accomplish this with a route resolve, but i can't get it to work. What am i doing wrong? Also my angular skills are a bit shabby so i aplogize in advance if my question is dumb.
Application.js :
var Application = angular.module('ReporterApplication', ['ngRoute']);
Application.config(['$routeProvider', '$interpolateProvider',
function($routeProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
$routeProvider
.when('/packing/scan.html', {
templateUrl: 'packing/scan.html',
controller: 'PackingScanController',
resolve: {
initData : Application.PackingScanInit()
}
})
.when('/packing/stats.html', {
templateUrl: 'packing/stats.html',
controller: 'PackingStatisticsController'
})
etc
and here is my Scan.js file :
Application.PackingScanInit = function ($q,$timeout,$http) {
var serverData = "";
$http.get('/packing/scan.action')
.success(function(data){
serverData = data;
})
.error(function(data){
serverData = data;
});
return serverData;
}
Application.controller('PackingScanController', ['initData', '$scope', '$http', function(initData, $scope, $http) {
var packer = this;
// Message log model
packer.messageLog = [{
status : "",
message : null
}];
the files are included in this order.
service are singletons means there are initialized only one but time but if you simply return from service it will be called one time but if you return a function from service it will be called again and again .See Below Sample for working.
var app = angular.module('ajay.singhApp', [])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve: {
myVar: function (repoService) {
return repoService.getItems().then(function (response) {
return response.data;
});
}
}
})
.when('/view2', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/view1'
});
}]);
app.factory('repoService', function ($http) {
return {
getItems: function () {
return $http.get('TextFile.txt');
}
};
});
Try this:
Application.PackingScanInit = function ($q,$timeout,$http) {
return $http.get('/packing/scan.action')
.success(function(data){
return data;
})
.error(function(data){
return data;
});
}
Also you have to adjust your resolve to this:
resolve: {
initData : Application.PackingScanInit
}
Here is a specific working example:
(function() {
angular.module('app',['ngRoute']);
function TestCtrl($scope, initData) {
$scope.value = initData;
}
angular.module('app').config(function($routeProvider) {
$routeProvider.otherwise({
template: '`<p>Dude {{value}}</p>`',
controller: TestCtrl,
resolve: {
initData: function($http) {
return $http.get('test.json') //change to test-e.json to test error case
.then(function(resp) {
return resp.data.value; //success response
}, function() {
return 'Not Found'; // error response
});
}
}
});
});
})();
http://plnkr.co/edit/SPR3jLshcpafrALr4qZN?p=preview

Loading data for controller in Angular.js with resolve and $resource

I'm trying to load a job by Id from the API and pass it to the controller.
.when('/jobs/edit/:id', {
templateUrl: 'partials/jobs/edit',
controller: 'JobCtrl',
resolve: function($routeParams, Job){
var jobId = $routeParams.id;
return {
job: function(){
return Job.get({ id: jobId});
}
};
}
})
Controller:
angular.module('App')
.controller('JobCtrl', function ($scope, Job, $location, $routeParams) {
$scope.newJob = data.job; //does not work
$scope.errors = {};
$scope.save = function (form) {
//...
};
});
Model:
angular.module('App')
.factory('Job', function ($resource) {
return $resource('/api/jobs/:id', {
id: '#id'
}, { //parameters default
update: {
method: 'PUT'
}
});
});
How do I get the data in the controller? My resolve block in the route is not even being executed.
Edit: this page has lots of examples of different types of resolving:
http://phillippuleo.com/articles/angularjs-timing-multiple-resource-resolves-ngroute-and-ui-router
It seems like you resolve implementation is incorrect.
You could try to change router like:
.when('/jobs/edit/:id', {
templateUrl: 'partials/jobs/edit',
controller: 'JobCtrl',
resolve: {
job: function (Job, $routeParams) {
return Job.get({id: $routeParams.id});
}
}
})
And get resoled data in controller by including Job into dependencies:
angular.module('App')
.controller('JobCtrl', function ($scope, job, $location, $routeParams) {
// job is resolved here
$scope.job = job;
$scope.newJob = {};
$scope.errors = {};
$scope.save = function (form) {
//...
};
});
UPDATED
If you want to use JobCtrl either for creating and editing, you can return null in resoled job for new-job-page. It means: There aren't any job yet, till you create one.
.when('/jobs/new', {
templateUrl: 'partials/jobs/new',
controller: 'JobCtrl',
resolve: {
job: function () {
return null;
}
}
})

Resources