Using AngularJS with $window.sessionStorage (using Onsen UI) - angularjs

I am trying to implement a simple login feature. I want to have the DOM load a different element based on whether the $window.sessionStorage.currentUserId5 session exists or not. But the conditional statement I have added to .run() just keeps using the else{} statement
<script>
var app = ons.bootstrap('app', ['onsen','angular-svg-round-progress','nvd3','ngStorage']).run(function($rootScope,$window){
if($window.sessionStorage.currentUserId5)
{
$("#menudiv").html('<ons-sliding-menu var="menu" id="menusliding" main-page="main.html" menu-page="menux.html" max-slide-distance="85%" type="reveal" side="left" ></ons-sliding-menu>');
}
else{
$("#menudiv").html('<ons-sliding-menu var="menu" id="menusliding" main-page="login.html" menu-page="menux.html" max-slide-distance="85%" type="reveal" side="left" ></ons-sliding-menu>');
}
});
</script>
<div id="menudiv"></div>
Controller
User clicks button and this is called, $window.sessionStorage should be created here
$http.post('http://xxx-xxx.us-east-1.elasticbeanstalk.com/apipost/checkuserlogin', parameter, config).success(function (data, status, headers, config) {
// if login, user session created, redirected to index.html
if(data['result'] == 'success'){
$window.sessionStorage.currentUserId5 = '5'
$window.location.reload();
}
else {
// else error pop up
ons.notification.alert({
message: 'Please try again'
});
}
})
.error(function (data, status, header, config) {
});

I don't want to be rude, but I think the question is not really related to Onsen UI. Even though you're using it, I doubt that the usage of Onsen UI changes your actual question. (Unless Onsen UI breaks the code in some way.)
What you seem to be using is the ngStorage module. From what I've seen it seems like the normal way to access local and sessionStorage is just by having them directly, rather than through $window.
So you can try to just require $sessionStorage and use it directly. If you think that the issue may be connected to some browser reloading somehow breaking the session etc you could try $localStorage and see if it works. The final thing you could try is just see if the normal localStorage and sessionStorage work for you.
And if you want to debug what happens then you can do something like
$http.post('...', parameter, config).success(function (data, status, headers, config) {
alert(data.result);
if(data['result'] == 'success'){
$window.sessionStorage.currentUserId5 = '5'
alert($window.sessionStorage.currentUserId5);
$window.location.reload();
}
else {
...
}
}
Usually it's better to use console.log instead of alert, but in this case alert can be better since it will stop the execution until you click ok.
The other option is to click the preserve log option in the browser inspector's console. To open the chrome console you can do Ctrl + Shift + J or Cmd + Opt + J. The other browsers also have similar consoles where you can see the logs from console.log. Usually these types of issues can be debugged without the need of external help.

Related

How to change the URL without reloading the page when back button is clicked in angularjs?

I am using angularjs for my app. It contains a newsfeed. If user needs to view the particular news, he has to click on that particular news and it will redirect to that news. And after viewing the particular news, if user wants to go back to news feed(previous page), he has to click on the browser back button. So, in this case, if user clicks on the browser back button, the newsfeed page is reloading again. But, I dont want like this. I want to disable the reload and take the user to the place where he was before. I browsed a lot on this issue, but there was no absolute solution given. Please, help me out.
When you go back, previous route will be triggered and data will be reloaded. If you want to prevent reloading, place a service in between and cache the data.
$routeProvider.
when('/loadFeeds',{
controller:'LoadFeedCtrl',
templateUrl:'pages/feeds.html',
resolve:{
initData : function(FeedService){
return $q.all(
{
data: FeedService.load()
}
);
}
}
})
And in your FeedService, instead of making http call try to see the data is already available
.service('FeedService',function($q,$timeoute){
this.feeds=[];
this.load = function(){
var deferred = $q.defer();
$timeout(function(){
if(feeds.length===0){
this.feeds.push({title:'First','id':1})
this.feeds.push({title:'Second','id':2})
this.feeds.push({title:'Third','id':3})
this.feeds.push({title:'Fourth','id':4})
}
deferred.resolve(this.feeds);
},2000);
return deferred.promise;
};
})
The timeout service could be replaced with $http or $resource. I used the timeout to simulate the delay
you can take an anchor link and on click event of anchor call this
javascript function
window.window.history.back();
here is the html code for it
<input type="button" id="alnkBack" onclick="window.window.history.back();" value="Back" class="button" />

Intercept route and modify it before ui-router responds in AngularJS

I'm using HTML5 pushstate on a mobile AngularJS website. When someone hits the desktop version, they get redirected to the mobile site. Sometimes the URL has a hash that the desktop site uses. The extra # is causing me digest loop problems.
I want to modify the route string before UI router even has a chance to act on it. Given:
http://www2.health.com.au/product/basic/#?blah I only want UI router to read the path /product/basic/.
I've tried adding a rule to the route provider (docs) that checks for '#?' and splits the string - but this seems to have no effect:
$urlRouterProvider.rule(function ($injector, $location){
var path = $location.url();
debugger;
if(path[path.length - 1].indexOf('#?')){
var splitpath = path.split('#?');
$location.replace().path(splitpath[0]);
return splitpath[0];
}
});
And the route ends up like this: http://www2.health.com.au/product/basic/#%252525252525252525252525252525252525252525252525252525252525252525252.......
With the error 10 $digest() iterations reached
I was under the impression that rules intercept the route, change it if possible and then pass the fixed route for ui-router to handle. Can anybody shed any light?
I am not particularly happy with this solution, but I ended up doing a manual bootstrap WITH A FREAKIN SETTIMEOUT!!! without it, angular.bootstrap() races the window.location = ... and wins unbelievably.
angular.element(document).ready(function(){
var loc = window.location.href,
index = loc.indexOf('#?');
if(index > 0){
alert('needsfix');
window.location = loc.substring(0, index);
setTimeout(function() {
angular.bootstrap(document, ['health3App']);
}, 500);
} else {
angular.bootstrap(document, ['health3App']);
}
})

Onsen UI show modal until page is completely loaded

I am trying to show the modal dialog while my page is being loaded. Right now I show the modal before the page push (e.g. app.navi.pushPage( 'detail.html' ) ). In the page init i have to go out and get some data from a third party API, and display it in a list. Once the request is complete and the list is populated I hide the modal.
The issue is that the modal is actually being hidden before the transition starts. Any ideas on how I can hide the modal once the transition is complete and the DOM is loaded?
Thanks!
Here there is an example that hides the modal after 2 seconds: http://onsen.io/guide/overview.html#UsingModal
In your case I guess you are using an HTTP request or something similar to access the third party API, so it's necessary to hide the modal after preparing all the data in the callback of the request:
$http.get('/third/party/API').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
myItemList = data[...];
... // refresh view, pushPage or whatever you need to prepare
modal.hide();
}).
error(function(data, status, headers, config) {
// Handle errors in request
});
Hope it helps!

How to show errors in angularjs resource?

I try to show a dialog error when the a web api fails. I am using bootbox for this purpose.
The code is:
OrderService.get(function(response) {
$scope.newOrder = response;
}, function(error) {
$bootbox.alert(error.statusText);
});
OrderService is a service:
app.factory('OrderService', [
'$resource', function($resource) {
return $resource('http://myweb/api/orders/neworder', {});
}]);
The first time that I open the web page, it works fine and the error message is displayed.
If I refresh the page, then the bootbox disable the entire screen and I cannot close the bootbox popup dialog.
If I replace $bootbox.alert(error.statusText); by alert(error.statusText);, then everything works fine.
If you are using some module to implement bootbox, 'cos $bootbox must injected
If not then, you can simple use without $:
OrderService.get(function(response) {
$scope.newOrder = response;
}, function(error) {
bootbox.alert(error.statusText);
});
from bootboxjs page:
Once you’ve got your dependencies sorted, usage is fairly
straightforward and much like any other JavaScript library you’ve ever
used. The library creates a single global instance of a bootbox object

How to multilingual url when user enter, copy paste or click url from other website

I have angularjs project implemented multi-language and using ui-router for routing. Every language will be have different url. Ex:
http://example.com/!#/en-us/english-title
http://example.com/!#/es-es/spanish-title
All state with url registered automatically when app run and load them from database. Ex:
angular.module('bxApp').run(["$http", function ($http) {
$http.get('/Home/Routes').success(function (result) {
result = result || {};
if (angular.isDefined(result) && result !== null) {
_.each(result.Routes, function (route) {
stateProvider.state(route.Name, {
url: route.Url,
templateUrl: route.TemplateUrl,
controller: route.Controller,
});
});
}
});
}]);
It work well but it will not work when user copy this link and paste to browser or click this link from other website . I think because of state can't found so it will be redirect to default and it does not keep url that user enter or copy.
In this case , How to do that?
Thanks,
You're declaring your states as a result of an HTTP call to your server: the problem is that these states are defined too late for the user to navigate to them when he pastes the URL in a new tab.
To understand, let's deconstruct what happens :
The user is on the initial page / other website, and copies the URL.
He pastes it in a new tab
Your angular application loads, finishes its config phase without having declared any of those states, and sends an HTTP call.
ui-router fails to route to a state matching the pasted URL, since the corresponding state is not here yet, and redirects to default
The HTTP response comes back, and your states are created (but too late).
How to make it work ?
My first reaction would simply not to store your states on your server. Unless you want the very core of your UX to be language-dependent, you don't have to do that.
But hey, let's say we want to do it anyway. I suggest you try this : declare a toplevel 'language' state, and have it load the other states in a resolve clause. This will 'block' the routing until the other states are declared :
angular.module('bxApp')
.config(['$urlRouterProvider', function ($urlRouterProvider) {
$urlRouterProvider
.state('language',{
url: '/:language',
resolve: {
childrenLoaded: ['$http', function ($http) {
// returning a promise is essential to have the 'waiting' behavior
return $http.get('/Home/Routes').then(function (data) {
var result = data.result || {};
if (angular.isDefined(result) && result !== null) {
_.each(result.Routes, function (route) {
$stateProvider.state(route.Name, {
url: route.Url,
templateUrl: route.TemplateUrl,
controller: route.Controller
});
});
}
});
}]
}
})
}]);
Again, this approach is probably asking for trouble : I strongly recommend you hardcode your states instead of storing them in a database. If all that varies from one language to another is the text and URL, then you will be fine with an URL param.

Resources