Closed ptitdje45 closed 7 years ago
resolve inside views is deprecated and doesn't work in ui-router 1.0. Which version do you use?
Also, you should annotate your clientPrepService.
"angular-ui-router": "^0.2.18", i did the annotate.
My new problem is that 204 http isn't considered as an error in angular. Is there a tricks to handle this ?
Can you show your ClientController?
Formally 204 isn't error. Error's codes start from 400.
@Anber
ClientController.$inject = ['$q', 'dataservice','logger', '$state', '$scope','$stateParams','communicationservice','clientPrepService'];
/* @ngInject */
function ClientController($q, dataservice, logger, $state, $scope,$stateParams, communicationservice, clientPrepService) {
var vm = this;
vm.client = clientPrepService[0];
activate();
ClientController. So when i call a good client, i can use it normally in my controller. This actually work perfectly.
I will talk about the logic because i'm new to resolve routing, don't hesitate to correct me if i'm wrong :
The problem is : - even if i have a empty client, the route resolve go the controller.
(function() {
'use strict';
angular
.module('app.client')
.run(appRun);
appRun.$inject = ['routerHelper'];
clientPrepService.$inject = ['dataservice','$stateParams'];
/* @ngInject */
function appRun(routerHelper) {
var otherwise = '/404';
routerHelper.configureStates(getStates(), otherwise);
}
function getStates() {
return [
{
state: 'dashboard.clients.client',
config: {
url: '/:idCli',
views: {
'@': {
templateUrl: 'app/clients/client/client.html',
controller: 'ClientController',
controllerAs: 'vm'
}
},
resolve: {
clientPrepService: clientPrepService
},
title: 'Client',
ncyBreadcrumb: {
label: '{{vm.idCli}}'
}
}
}
];
}
function clientPrepService(dataservice, $stateParams) {
return dataservice.sendRequest('get','clients/idReient/' + $stateParams.idCli);
}
})();
Again my client.route.js, should i do something more to explain in my clientPrepService if the returned data is empty to do a $state.go('404') ? Note that the url is url: '/:idCli'
I just confirmed that the clientPrepService is called before my controller so it looks like it's pretty ok for the code structure. And even if i do a 404 the route go to the controller
Im a bit lost atm
function handleRoutingErrors() {
// Route cancellation:
// On routing error, go to the dashboard.
// Provide an exit clause if it tries to do it twice.
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error) {
if (handlingStateChangeError) {
return;
}
stateCounts.errors++;
handlingStateChangeError = true;
var destination = (toState &&
(toState.title || toState.name || toState.loadedTemplateUrl)) ||
'unknown target';
console.log('destination :' + destination + '!');
var msg = 'Error routing to ' + destination + '. ' +
(error.data || '') + '. <br/>' + (error.statusText || '') +
': ' + (error.status || '');
logger.warning(msg, [toState]);
$location.path('/dev/build');
}
);
}
The route-helper from John papa
If the resolve return a bad request 204 / 404 etc.. I go directly to the 404.html
No. Resolve returns promise. If a http request returns 204, promise resolves with an empty payload. If a request returns 404, promise rejects. I don't know what is happening in your dataservice, but it looks like a simple wrapper for $http with default behavior. If I correctly understood you, we have three possible options:
You can merge 2nd and 3rd options to one: just add .catch(() => null)
to sendRequest response. After this, you can catch empty client in onEnter hook.
P.S. You should use either $inject nor @ngInject otherwise your function will be annotated twice.
Yeah the problem is coming from my dataservice which allow everything and just return ''; if the code returneed by the api is '204' or '404' etc...
So i'm working on the dataservice to improve that.
Here is my actual .then() for the $http request
function success(response) {
if (typeof response.data.error !== 'undefined') {
if (response.data.error.code === 404 || response.data.error.code === 204) {
return exception.catcher('Request failed for ' + type + ' : ' + mainURL + path)(response);
}
}
else {
return response.data;
}
}
Works perfect but i'm forced to stop showing my loggers because there is too much view that does a 204 ( success but nothing to give back ). I don't really get ur .catch idea. Can you explain a little bit more ? :) Thank you by far @Anber
What is exception.catcher
?
Success callback isn't called for errors. You should use a second argument of then
for suppress all errors and return null-client (https://docs.angularjs.org/api/ng/service/$q).
$http.get('…').then(response => response.data).catch(() => null)
or
$http.get('…').then(response => response.data, () => null)
Then you can do something like this
…
resolve: {
clientPrepService: clientPrepService,
},
onEnter: /* @ngInject */ function(clientPrepService){
if (!clientPrepService) $state.go(...); // redirect to 404
}
…
(function() {
'use strict';
angular
.module('blocks.exception')
.factory('exception', exception);
/* @ngInject */
function exception($q, logger) {
var service = {
catcher: catcher
};
return service;
function catcher(message) {
return function(e) {
var thrownDescription;
var newMessage;
if (e.data && e.data.description) {
thrownDescription = '\n' + e.data.description;
newMessage = message + thrownDescription;
}
e.data.description = newMessage;
logger.error(newMessage);
return $q.reject(e);
};
}
}
})();
This is my exeption catcher that return the $q.reject.
Success callback isn't called for errors.
In my case, all $http request are success, that's why im doing the $q.reject in my success. I need that when i got an empty $http response, that's not going into exception.catcher, except when i do my routes
Anyway you can add .catch(() => null)
after your then
and check client in onEnter hook.
Got it, thank you for ur patiente ! Perfect !!! :) love the way that you easely implement in es6.
Hi there,
Having a little problem on my resolve to avoid a user to go on a user that doesn't exist.
client.route.js `(function() { 'use strict';
angular .module('app.client') .run(appRun);
appRun.$inject = ['routerHelper', '$stateParams', 'dataservice']; / @ngInject / function appRun(routerHelper) { routerHelper.configureStates(getStates()); }
function getStates() { return [ { state: 'dashboard.clients.client', config: { url: '/:idCli', views: { '@': { templateUrl: 'app/clients/client/client.html', controller: 'ClientController', controllerAs: 'vm', resolve: { clientPrepService: clientPrepService } } }, title: 'Client', ncyBreadcrumb: { label: '{{vm.idCli}}' // angular-breadcrumb's configuration } } } ]; }
function clientPrepService(dataservice, $stateParams) { console.log('uh ?'); return dataservice.sendRequest('get','clients/idRefClient/' + $stateParams.idCli); }
})(); `
I don't even get my console.log in the clientPrepService. I'm trying to follow the styleguide of John Papa. All my clients are currently rejected. ( all works without the resolve ).
Thanks by advance,