$resource is not changing the id of the url - javascript

I am in trouble to change the id param of a URL passed to $resource. Apparently the value isn't changing to the correct value that it recive from Resource.get(id:$routeParams.id), even when I put a fixed value (Resource.get(id:1)), resulting in the following error:
TypeError: encodeUriSegment is not a function
When I change the id param of the URL for a fixed value (baseURL+'client/1'), it works.
This is my font:
app.js
'use strict';
angular.module('serviceOrder',['ngRoute','ngResource'])
.config(function ($routeProvider,$locationProvider) {
/*$locationProvider.html5Mode({
enabled: true,
requireBase: false
});*/
$routeProvider.when('/clients', {
templateUrl: 'views/clients.html',
controller: 'ClientController'
});
$routeProvider.when('/newclient',{
templateUrl: 'views/client.html',
controller: 'NewClientController'
});
$routeProvider.when('/editclient/:id',{
templateUrl: 'views/client.html',
controller: 'EditClientController'
});
$routeProvider.otherwise({redirectTo: '/clients'});
});
controler.js
'use strict';
angular.module('serviceOrder')
.controller('EditClientController',['$scope','$routeParams','clientService',
function ($scope,$routeParams,clientService) {
$scope.message = 'Loading ...';
$scope.client = {};
$scope.phone = {id:'',brand:'',model:'',state:'',esn:''};
debugger;
clientService.getClients().get({id:$routeParams.id})
.$promise.then(
function (response) {
$scope.client = response;
},function (error) {
$scope.message = 'Error: ' + error;
}
);
}]);
service.js
'use strict';
angular.module('serviceOrder')
.constant('baseURL', 'http://localhost:8080/service-order-rest/rest/')
.service('clientService',['$resource','baseURL',function ($resource,baseURL){
this.getClients = function () {
return $resource(baseURL+'client/:id',null,{'update':{method:'PUT'}});
};
}]);

Your param defaults are not being configured properly. To achieve this, according to $resource's docs, you must especify the pattern of your API method that will receive params like { id: '#id' } instead of null.
$resource(baseURL + 'client/:id', //url
{ id: '#id' }, // parameters
{
'update': { method: 'PUT' } // methods
});

We have a bug here :
return $resource(baseURL+'client/:id',{id: youridhere} ,{'update':{method:'PUT'}});

Related

RouteProvider resolve AngularJS

Here is my code :
Js:
angular.module('main', [])
.config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$routeProvider.when('/tables/bricks', {
controller: "myController",
resolve: {
"check" : function($location){
if(!$scope.bricks) {
$route.reload();
}
}
},
templateUrl: 'tables/bricks.html'
});
$routeProvider.otherwise({
redirectTo: '/tables/datatables'
});
}
])
.controller('myController', function($scope, $location, $http) {
var vm = this;
$scope.Bricks = function(){
$location.path('/tables/bricks');
};
vm.getbricks = function(n){
var url = n;
$http({
method: 'GET' ,
url: url,
})
.then(function successCallback(data) {
$scope.bricks = data.data;
console.log($scope.bricks);
}, function errorCallback(response) {
console.log(response);
console.log('error');
});
};
});
HTML:
<button ng-click="vm.getbricks(n.bricks_url);Bricks();"></button>
After click the button in html, my page goes into /tables/bricks, but nothing happend, because resolve probably is wrong. What I want - that i could go to /tables/bricks only then, when $scope.bricks exist, so only when vm.bricks() will be called.
Thanks for answers in advance!
I think your problem is that the vm.getbricks will always return something (in success or error handler), so will never be falsy, and you will always call the Bricks() constructor. try to return true on success callback and false in error callback.
$scope is for controllers, which it can't reach in the config. Instead, you should be returning something from a service, which will be called during your resolve. E.g. if(YourService.getbricks())
Solution: move your logic from a controller into a service. And make sure to return a value from it that can be checked in the config.
app.service('BrickService', function() {
this.getbricks = function(url) {
return $http.get(url) // return the Promise
.then(function(response) {
return response.data; // return the data
}, function(error) {
console.log(error);
});
};
});
With this you can inject the service into the config and run its function.
angular.module('main', [])
.config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$routeProvider.when('/tables/bricks', {
controller: "myController",
resolve: {
"check": function(BrickService) { // inject
if ( BrickService.getbricks() ) { // run its function
$route.reload();
}
}
},
templateUrl: 'tables/bricks.html'
});
$routeProvider.otherwise({
redirectTo: '/tables/datatables'
});
}
])
You can also use the loaded values in the controller after they have been resolved. For that, you would need to simply return it. So change the logic to this:
resolve: {
"check": function(BrickService) { // inject
var bricks = BrickService.getbricks(); // run its function
if ( bricks ) {
$route.reload();
}
return bricks; // return the result (note: it's not a Promise anymore)
}
}
Then you can inject this resolve into your controller:
.controller('myController', function($scope, $location, $http, check) {
var vm = this;
vm.bricks = check;
...
(Note check was added)

Getting Array of duplicate object instead of single object

I am writing a rather simple crud app, however, i seem to be stuck on the edit (Edit Controller) portion code. i have a list of student, i select one for update . but i get the error "Expected response to contain an object but got an array".
When i query the webservice directly, i get
But when i inspect elements and go to the network tab, i see this
here is my code.
var StudentManagement = angular.module('StudentManagement', ['ngRoute','ngResource','ui.bootstrap']);
StudentManagement.config(function ($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "list.html",
controller: "HomeController"
})
.when("/add", {
templateUrl: "add.html",
controller: "AddController"
})
.when("/edit/:editId", {
templateUrl: "edit.html",
controller: "EditController"
})
.otherwise({
redirectTo: "/"
});
});
StudentManagement.factory('Student', function ($resource) {
return $resource('/api/Student/:id', { id: '#id' }, { update: { method: 'PUT' } });
});
StudentManagement.controller("HomeController",
function ($scope, $location, Student) {
$scope.search = function () {
$scope.students = Student.query();
};// end search
$scope.reset = function ()
{
$scope.search();
}// end reset function
$scope.search();
});
StudentManagement.controller("EditController",
function ($scope, $location, $routeParams, Student) {
// get the student given the specific id
var id = $routeParams.editId;
$scope.student=Student.get({id: id});
$scope.updateForm = function () {
Student.update({id:id}, $scope.student, function () {
$location.path('/');
});
}// end edit function
$scope.cancelForm = function () {
$location.path('/');
}// end cancel function
});
You are returning array of object from server.
So,you should add isArray : true in resource defination.
$resource('/api/Student/:id', { id: '#id' },
{ update: { method: 'PUT',isArray : true}
});
Or
you can return object of object from server
if you want to make current code workable

How to handle http 302 response in angularjs

I have a java filter, that checks session attribute username. When the username is null then redirect to path /login.I access path /index.html when username is null, I got a HTTP code 302, so I add interceptor in angularjs. But I access /index.html got a error when username is null.
var testApp = angular.module('testApp', [ 'ngRoute', 'myApp' ]);
testApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/anchor/historyAttendance/:uid',{
templateUrl : 'anchor/historyAttendance.html',
controller : 'AnchorHistoryAttendanceCtrl'
}).when('/anchor/list', {
templateUrl : 'anchor/list.html',
controller : 'AnchorListCtrl'
}).otherwise({
redirectTo : '/'
});
} ]);
var app = angular.module('myApp', [ 'ngTable', 'ngFileUpload', 'ngDialog' ,'ui.colorpicker', 'ngCsv', 'ngSanitize'],function ($provide,$httpProvider) {
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q) {
return {
// optional method
'request': function(config) {
// do something on success
console.log(config);
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
console.log(response);
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});
app.directive('fontColor', function () {
return {
restrict: 'E',
scope: {},
replace: false,
template: '<div color-picker default-color="#ff0000" class="font-color" ng-style="{\'background-color\': selectedFontColor}"></div>',
link: function (scope) {
scope.selectedFontColor = '#f00';
scope.$on('colorPicked', function (event, color) {
scope.selectedFontColor = color;
});
}
}
});
the error in chrome like that:
You can not handle 302 response from a server because browsers do this before the Angular is notified. In a way, Angular response interceptor will never get a hand on this response.
It is properly explained here: Handle HTTP 302 response from proxy in angularjs or https://stackoverflow.com/a/29620184/2405040
It seems that you have created myApp after creation of testApp while you have injected myApp with testApp which does not look correct.
Make sure before injecting any of the module it should be available.
Try below code:
var app = angular.module('myApp', [ 'ngTable', 'ngFileUpload', 'ngDialog' ,'ui.colorpicker', 'ngCsv', 'ngSanitize'],function ($provide,$httpProvider) {
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q) {
return {
// optional method
'request': function(config) {
// do something on success
console.log(config);
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
console.log(response);
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
console.log(rejection);
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});
app.directive('fontColor', function () {
return {
restrict: 'E',
scope: {},
replace: false,
template: '<div color-picker default-color="#ff0000" class="font-color" ng-style="{\'background-color\': selectedFontColor}"></div>',
link: function (scope) {
scope.selectedFontColor = '#f00';
scope.$on('colorPicked', function (event, color) {
scope.selectedFontColor = color;
});
}
}
});
var testApp = angular.module('testApp', [ 'ngRoute', 'myApp' ]);
testApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/anchor/historyAttendance/:uid',{
templateUrl : 'anchor/historyAttendance.html',
controller : 'AnchorHistoryAttendanceCtrl'
}).when('/anchor/list', {
templateUrl : 'anchor/list.html',
controller : 'AnchorListCtrl'
}).otherwise({
redirectTo : '/'
});
} ]);

Get data before page load in angularJS

I am trying to fetch a drop downlist before the page load using angular $http. I tried few combinations but it keep on giving the same error:
Error: [$injector:unpr] Unknown provider: officeListProvider <- officeList <- myController
http://errors.angularjs.org/1.4.3/$injector/unpr?p0=officeListProvider%20%3C-%20officeList%20%3C-%20myController
I am few weeks old in angular so please pardon in case of any silly mistakes.
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when('../../home/goEeUpdateAngular.obj', {
templateUrl: '/employee_update_angular.jsp',
controller: 'myController',
resolve: {
officeList: function(officeListFactory) {
return officeListFactory.getOfficeList();
}
}
});
}]);
myApp.factory('officeListFactory', function($http, $window) {
$window.alert("Hi");
var factoryResult = {
getOfficeList: function() {
var promise = $http({
method: 'GET',
url: '../../home/goOfficesList.obj'
}).success(function(data, status, headers, config) {
console.log (data);
return data;
});
return promise;
}
};
console.log (factoryResult.getOfficeList());
return factoryResult;
});
myApp.controller('myController',function ($scope,officeList) {
$scope.officeListFactory = officeListFactory.data;
});
The error says "officeListProvider" is not present or not visible, you need to add it as dependency.
Please try the below change:
var ctrl = angular.module('myApp.controllers', []);
to
var ctrl = angular.module('myApp.controllers', ['myApp.services']);
and also please use the same service name it is either srvOfficeList or officeList, and also check your service factory, it is not right - example:AngularJS : factory $http service
Hope it will fix the issue.
Please try to create a CodePen (or similar tool) while posting the question, so that the Answer can tried/fixed in there and shared back with you.
In controller you should call only officeList. Here is the working JSFIDDLE. I too sample webapi instead of your url
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when('../../home/goEeUpdateAngular.obj', {
templateUrl: '/employee_update_angular.jsp',
controller: 'myController',
resolve: {
officeList: function(officeListFactory) {
return officeListFactory.getOfficeList();
}
}
});
}]);
myApp.factory('officeListFactory', function($http, $window) {
$window.alert("Hi");
var factoryResult = {
getOfficeList: function() {
var promise = $http({
method: 'GET',
url: '../../home/goOfficesList.obj'
}).success(function(data, status, headers, config) {
console.log (data);
return data;
});
return promise;
}
};
console.log (factoryResult.getOfficeList());
return factoryResult;
});
myApp.controller('myController',function ($scope,officeList) {
$scope.officeListFactory = officeList.data; //changes are made here
});

AngularJS : angular-ui-router always redirects to $urlRouterProvider.otherwise location

I'm trying to create an SPA where you have to be logged in to access almost everything. So naturally, the default screen you see is the login screen. However, after a user has logged in, no matter what the ui-sref is, ui-router redirects to the login page (even when the user is authenticated). Here is my ui-router code:
(function () {
'use strict';
angular
.module('app', ['ui.router', 'satellizer'])
.config(function ($stateProvider, $urlRouterProvider, $authProvider, $httpProvider, $provide) {
$httpProvider.interceptors.push(['$q', '$injector', function($q, $injector){
return {
responseError: function (rejection) {
var $state = $injector.get('$state');
var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
angular.forEach(rejectionReasons, function (value, key) {
if (rejection.data.error === value) {
localStorage.removeItem('user');
$state.go('auth');
}
});
return $q.reject(rejection);
},
response: function(response) {
var authorization = response.headers('authorization');
if(authorization !== null) {
authorization = authorization.substr(7).trim();
//console.log(authorization);
var $auth = $injector.get('$auth');
$auth.setToken(authorization);
}
return response;
}
}
}]);
$authProvider.loginUrl = 'mingdaograder/api/authenticate';
$stateProvider
.state('users', {
url: '/users',
templateUrl: 'views/userView.html',
controller: 'UserController as user'
})
.state('subjects', {
url: '/users/:user_id/subjects',
templateUrl: 'views/subjectsView.html',
controller: 'SubjectsCtrl as subjectsCtrl'
})
.state('subject', {
url: '/users/:user_id/subjects/:subject_id',
templateUrl: 'views/subjectView.html',
controller: 'SubjectCtrl as subjectCtrl'
})
.state('auth', {
url: '/auth',
templateUrl: 'views/authView.html',
controller: 'AuthController as auth'
});
//.state('otherwise', {
// url: '*path',
// templateUrl: 'views/authView.html',
// controller: 'AuthController as auth'
//});
//$urlRouterProvider.otherwise('/auth');
$urlRouterProvider.otherwise(function($injector, $location) {
console.log("Could not find " + $location);
$location.path('/auth');
});
})
.run(function ($rootScope, $state, $log) {
$rootScope.$on('$stateChangeStart', function (event, toState) {
console.log(toState.name);
var user = JSON.parse(localStorage.getItem('user'));
if (user) {
$rootScope.authenticated = true;
$rootScope.currentUser = user;
}
}
);
}
);
})();
Anytime I try to use $state.go(any state name here) or even type the address into the address bar, I am always redirected to the auth state. On the console the message is "Could not find http://localhost/#/" for every single route. I can type in http://localhost/#/users/5/subjects and I get the same message.
Here is one of my controllers doing a redirect:
(function () {
'use strict';
angular
.module('app')
.controller('AuthController', AuthController);
function AuthController($auth, $state, $http, $rootScope, $log) {
var vm = this;
vm.loginError = false;
vm.loginErrorText;
vm.login = function () {
var credentials = {
username: vm.username,
password: vm.password
};
$auth.login(credentials).then(function () {
return $http.get('api/authenticate/user');
}, function (error) {
vm.loginError = true;
vm.loginErrorText = error.data.error;
}).then(function (response) {
var user = JSON.stringify(response.data.user);
localStorage.setItem('user', user);
$rootScope.authenticated = true;
$rootScope.currentUser = response.data.user;
//$log.info('From AuthCtrl: ' + $rootScope.currentUser.id);
$state.go('subjects', {user_id:$rootScope.currentUser.id});
});
}
}
})();
Any ideas what I'm doing wrong? Thanks a lot for your time.
Update: Ok, I haven't found a way to fix it but I think I may have found a possible cause. It seems to only happen for the routes with parameters. For example, if I go to the users state, whose path is /users, there is no redirect. However, if I go to the subjects state, whose path is /users/:user_id/subjects, it does redirect. It's like the Url matching service can't recognize that /users/5/subjects matches /users/:user_id/subjects, so redirects. Any ideas how to work around this?
I found I didn't have a '/' at the beginning of my initial state url. Every time I navigated to the state, the missing '/' seemed to push it into the stateProvider.otherwise.
state1: 'opportunity'
state1Url : '/opportunity/' <== added initial forward slash to make it work.
state2: 'opportunity.create'
state2Url : 'create/'
The first path to be recognised will be the selected as the current location. This means that the order of your route definitions is crucially important. In your case you only have a single catch-all otherwise route definition and since all routes match this then all routes are directed to your login page ignoring any other route definitions you may have, including all your stateProvider state definitions.
One way to fix this is to remove the urlRouterProvider route definition altogether and instead use the *path syntax provided by ui-router to create an alternative otherwise state (which must be defined last for the same reasons given above).
Therefore your code might look something like this:
$stateProvider
.state('auth', {
url: '/auth',
templateUrl: 'views/authView.html',
controller: 'AuthController as auth'
})
.state('users', {
url: '/users',
templateUrl: 'views/userView.html',
controller: 'UserController as user'
})
.state('subjects', {
url: '/users/:user_id/subjects',
templateUrl: 'views/subjectsView.html',
controller: 'SubjectsCtrl as subjectsCtrl'
})
.state('subject', {
url: '/users/:user_id/subjects/:subject_id',
templateUrl: 'views/subjectView.html',
controller: 'SubjectCtrl as subjectCtrl'
})
.state("otherwise", {
url: "*path",
templateUrl: 'views/authView.html',
controller: 'AuthController as auth'
});
From experience, this is either due to the / missing at either the beginning or the end of the url route property definition.
Make sure for parent routes to add the initial forward slash to your routes.
.state('checkers', {
url: '/checkers/',
templateUrl: 'checkers.html',
controller: 'CheckersController',
title: 'Checker',
})
(function () {
'use strict';
angular
.module('app', ['ui.router', 'satellizer'])
.config(function ($stateProvider, $urlRouterProvider, $authProvider, $httpProvider, $provide) {
$httpProvider.interceptors.push(['$q', '$injector', function($q, $injector){
return {
responseError: function (rejection) {
var $state = $injector.get('$state');
var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
angular.forEach(rejectionReasons, function (value, key) {
if (rejection.data.error === value) {
localStorage.removeItem('user');
$state.go('auth');
}
});
return $q.reject(rejection);
},
response: function(response) {
var authorization = response.headers('authorization');
if(authorization !== null) {
authorization = authorization.substr(7).trim();
//console.log(authorization);
var $auth = $injector.get('$auth');
$auth.setToken(authorization);
}
return response;
}
}
}]);
$authProvider.loginUrl = 'mingdaograder/api/authenticate';
$stateProvider
.state('users', {
url: '/users',
templateUrl: 'views/userView.html',
controller: 'UserController as user'
})
.state('subjects', {
url: '/users/:user_id/subjects',
templateUrl: 'views/subjectsView.html',
controller: 'SubjectsCtrl as subjectsCtrl'
})
.state('subject', {
url: '/users/:user_id/subjects/:subject_id',
templateUrl: 'views/subjectView.html',
controller: 'SubjectCtrl as subjectCtrl'
})
.state('auth', {
url: '/auth',
templateUrl: 'views/authView.html',
controller: 'AuthController as auth'
});
//.state('otherwise', {
// url: '*path',
// templateUrl: 'views/authView.html',
// controller: 'AuthController as auth'
//});
//$urlRouterProvider.otherwise('/auth');
$urlRouterProvider.otherwise(function($injector, $location) {
console.log("Could not find " + $location);
$location.path('/auth');
});
})
.run(function ($rootScope, $state, $log) {
$rootScope.$on('$stateChangeStart', function (event, toState) {
console.log(toState.name);
var user = JSON.parse(localStorage.getItem('user'));
if (user) {
$rootScope.authenticated = true;
$rootScope.currentUser = user;
}
}
);
}
);
})();

Categories

Resources