Handle AngularJS errors while loading template file - javascript

I create an app with requirement of template files being in two folders - first is available without restrictions and second is available only for logged in users.
Things are complicating when somebody refresh the page and session expire before. Angular throws error (e.g. 401) in console while loading template file which I want to avoid. Is there a way to catch that event and access response status to for e.g. redirect the page?

For your case, we can catch the error and redirect to a page with the help of $location.url(). Here is the concept. Now i have a controller and in that, i have success function and error function. Whenever we get an error, the error function will run and we can pass the link of the page you want to redirect.
$http.get(url,[params])
.success(function(data, status, headers, config){
// bind your data to scope
})
.error(function(data, status, headers, config) {
$location.url('/404');
});
By the use of $routeProvider, you can configure the function something like
this :
$routeProvider
.when('/404', {
templateUrl: '404.html',
controller: 'yourcontroller'
});
And you can see the description for $location.url() here
Hope it works

Related

Pretty Urls in AngularJs and Laravel not working

I'm developing an application using Laravel and AngularJS. For AngularJS pretty URL , i have set $locationProvider.html5Mode(true) and it's working fine. But suppose my url is http://localhost:8000/demo and if i refresh the page, I'm getting NotFoundHttpException in compiled.php line 7693:
Here is my angular's routes.
function($routeProvider,$locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/', {
templateUrl: 'partials/index.html',
controller: 'indexController'
}).
when('/dom',{
templateUrl:'partials/dom.html',
controller:'DomController'
}).
when('/demo',{
templateUrl:'partials/demo.html',
controller:'DemoController'
});
}]);
And here's my laravel's route.
Route::get('/', function(){
return view('index');
});
I'd appreciate a little help.
Thanks!
The problem here is that the web server will pick up http://localhost:8000/demo when you refresh the page, and try to handle the request. It's not aware that you wish to use html5 routing. So it will parse the request, say "oh, I should pass this to public/index.php and be done with it". And then public/index.php will receive it and throw an error since the route doesn't exist in Laravel.
What you need to do is to make a catch all type of route in Laravel, and then let Angular's routing take over. You then render your index view on every single request. There's a great answer here on SO on how you do that in Laravel 5: How do I catch exceptions / missing pages in Laravel 5?
This is pseudo code and will not work, just to show an example:
Route::get('*', function() {
return view('index');
});
So, render the index view on every request and then let Angular handle the routing from there.

Posting data to JSON - Angular .post

I am working on an application and am having an issue posting to a .JSON file in my assets. I am working with an Angular based application. The error code I get is 404 with a response of: Cannot POST /assets/data/card-stack.json. Now the problem is, when I work with my get to retreive the JSON data it works perfect. It is only when I am using .post. Here is what I am doing:
$http.get('./../../assets/data/card-stack.json').success(function(data) {
$scope.cards = data;
// Set the showdown images from the card data grabbed from the card-stack.json file
$scope.showdowns = [
$scope.cards[0].url,
$scope.cards[1].url,
$scope.cards[2].url,
$scope.cards[3].url
];
});
// Simple POST request example (passing data) :
$http.post('./../../assets/data/card-stack.json', {url : './../images/banana.jpg'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
console.log(data);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Suggestions?
A .json file is a static file that just contains json data so you won't be able to post to it. Instead you would need to use a server side page or service such as php to process the posted data.
Try to set the $http header:
$http.defaults.headers.post["Content-Type"] = "application/json";
Try it.

AngularJS ui-router to a state but use different URL

In my AngularJS application I want to catch errors and send the user to a 404 state like so:
$rootScope.$on('$stateNotFound', function(event, unfoundState, fromState, fromParams){
//console.log(unfoundState.to);
//console.log(unfoundState.toParams);
//console.log(unfoundState.options);
$state.go('404');
});
This is for when a user clicks a bad link (e.g. has no state, as ones with states but no content are handled by the otherwise method) in the app, etc.
The code loads the 404 state fine:
.state('404',
{
views: {
'body': {
templateUrl: 'partials/404.html',
}
}
});
But what I want to do is change the URL to the state they tried to access, so basically load the 404 state but use the incorrect URL (as a 404 would work in a server environment).
I've looked into doing:
history.replaceState(null, null, unfoundState.to);
$state.go('404');
But that causes major errors in the app and changes the URL but not the state!
How can I do this?
Try this to catch all URLs not matching any of your previous routes :
.state("404", {
url: "*path", // will catch all URLs
templateUrl: 'partials/404.html'
})
According to the docs, I think you can do:
$state.go('404',{},{location:false});
Note: I'm in the process of creating a plunkr to verify but I don't have time to finish it up completely right now

Angular logs HTTP error before handling it

I have the following mechanism (ignore the simplicity for the moment please) when a user clicks on a button on a dead simple login form:
$scope.login = function () {
$http.post('/rest/authenticate', {
userName: $scope.userName,
password: $scope.password
}).
success(function (data, status, headers, config) {
//handle success, etc
}).
error(function (data, status, headers, config) {
//hanlde errors, etc
});
};
The method is calling a REST service that could return a String as an answer if the proper credentials are provided or an error (400, 401) if they are not good. The success method gets executed when the good user/pass is given and the error function also executes if the REST call returns some HTTP error.
My problem is that if any kind of error happens, BEFORE the error method gets executed, angular displays the error in the browser console like this:
POST http://server.address/rest/authenticate 400 (Bad Request)
This originates from angular.js (line 8113):
xhr.send(post || null);
It even displays it before a http interceptor's 'responseError' method. Using non-compressed angular version 1.2.14
How can I turn this unnecessary logging off?
zeroflagL's comment is valid and I found no solution to this "issue"

Download a file from Angular.js with Express.js

In my MEAN application I need to provide a link to download a file, the link must be hidden and not accessible by unauthorized users.
So I came up with this idea of keeping the files inside the server directory and let Angular.js send with ng-click="download()" an $HTTP request to express.js with the file ID to download, and (possibly) the user id/pwd.
First of all is this a safe solution?
Second, here is my code that doesn't work, there are no errors whatsoever, but I can't even get the download dialog box to open:
Client Side
$scope.download=function(){
$http({method:'GET', url:'/download/'+image[0]['_id']}).
success(function(data, status, headers, config) {
var element = angular.element('<a/>');
element.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
target: '_blank',
download:'test.csv'
})[0].click();
}).
error(function(data, status, headers, config) {
});
}
Server Side
app.namespace('/download/:documentID*', function() {
app.all('/', function(req, res, next){
res.download('images/download/test.tif', 'test.tif', function(err){
if (err) {
} else {
next();
}
});
});
})
Last time I checked you couldn't trigger a download via ajax. ;-)
You'll need to create a <a> with e.g. target="_blank" so it opens up in a new tab/window. Don't know about your authentication though, I wouldn't send them in cleartext. You could work around that by checking the credentials in your ajax request and then open a new tab/window so that the file can be downloaded with some kind of one-time token. You'll need some server-side changes ofc.

Categories