3

I've doing some research on this topic, but I can't seem to move forward, most likely for not being able to use the correct keywords to explain my problem.

I'm developing a website with AngularJS, and some of the user actions on it require authentication, like adding a certain item to its favorites, commenting on a post, follow a user, etc.

Every time a person (non logged-in user) attempts one of this actions, he gets prompted with a modal to perform the log-in action. In order to better handle the app state and consistency, I'm doing a page reload. This means losing the state where the user was before the log-in. Imagine trying to favorite a item which resulted from a filtered search and the results were paginated with infinite-scrolling; handling all this information seems unfeasible after a full-page reload, since the data is kept in the controller's $scope. I'm trying to pick an edge case, so you can better understand the gravity of my situation.

Is there a way to keep a state on Angular, like for example how PHP handles it, by attaching these parameters on the URL and performing them when all necessary conditions are fulfilled?

Solving this, would probably help me out on other scenarios, like when sending a newsletter where I'd send a URL with the action for the user to perform, such as:

http://www.example.com/like?item=123412

Meaning the user would try to like/favorite this particular item. If already logged in, like it, otherwise prompt login and perform it after.

On this question I'm suggesting the parameters approach, but you happen to know any other, I'm open to any suggestions that might point me to the right direction.

Thank you.

NunoM
  • 293
  • 3
  • 17

3 Answers3

2

Yes, look into storage. On MDN: https://developer.mozilla.org/en/docs/Web/Guide/API/DOM/Storage#localStorage

There are quite a few angular packages available that handle this for you. There also are some good bundles for localStorage and JWT.

Here on SO I found a good example on how to do it without packages: https://stackoverflow.com/a/25430797/2433843 (Look at the Plunker demo)

Edit: had to look up the name, but angular-locker found here kind of solved it for me. I used it in combination with this developers JWT package for Laravel for the API, but there are quite a few more if you enter angular storage into your search engine, such as ngStorage (note: not official, despite the ng found here).

Community
  • 1
  • 1
Francesco de Guytenaere
  • 4,443
  • 2
  • 25
  • 37
  • This seems great. Will have to take a deeper look into it. It doesn't solve all the described problems, but it's a great step forward to a solution. Thanks. – NunoM Jul 01 '15 at 15:08
0

Okay lets say these are your states every view u have has a state in this example you have login / mandant / settings so when the user changes state u catch him by listening to $stateChange and redirect if he is not allowed to go there

.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider

// setup an abstract state for the tabs directive
.state('login', {
params: 8,
url: "/login",
templateUrl: "templates/login.html",
controller: "LoginCtrl"
})

.state('settings', {
  params: 8,
  url: '/settings',
  templateUrl: "templates/settings.html",
  controller: "SettingsCtrl"
   })

.state('mandant', {
params: 8,
url: '/mandant',
templateUrl: "templates/mandant.html",
controller: "MandantCtrl"
})
});

In your MainController you simpy use

 $rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
    if(userLoggedIn == true){
      //user is allowed
    }else{
      //user is not allowed
     $location.path('/login');
    }
});

So you are simply checking for some kinda login token or session and if its not present you just redirect the user to login or whatever

stackg91
  • 584
  • 7
  • 25
  • But this approach doesn't send him back to where he was, nor performs the action he was attempting, because we're not keeping that data. Unless I misunderstood your example. – NunoM Jul 01 '15 at 14:48
0

Personally i'd do it like so, basically just store the info in a service!

myApp.service('viewStateService', function() {
    this.someController['data'] = '';
    this.someController['currentRecord'] = '';
    // basically add as many properties as you like.
});

myApp.controller('someController', function($scope, viewStateService){
  if(viewStateService.data != ''){
     $scope.data = viewStateService.someController['data'];
     $scope.currentRecord = viewStateservice.someController['currentRecord'];

  } else {
    // grab the data normally.
  }

  $scope.$on("$destroy", function() {
     viewStateService.someController['data'] = $scope.data;
     viewStateService.someController['currentRecord'] = $scope.currentRecord;
  });
});

I'm on my mobile so this is untested but basically just store any info you need to a service and then call it back in when the controller loads.

Mrk Fldig
  • 4,244
  • 5
  • 33
  • 64