2

I'm having trouble figuring out how I could pass a parameter to a function that is a part of resolve of ngRoute.

In my case I'm doing stuff with tokens. These tokens are typed, so you cannot use the same token for confirming and email and reseting a password. Here's how my routes are defined:

.when("/confirm/:token", {
    controller: "confirmEmailController",
    templateUrl: "/app/views/confirmEmail.html",
    resolve: {
        tokenStatus: getTokenStatus
    }
})
.when("/reset/:token", {
    controller: "resetPasswordController",
    templateUrl: "/app/views/resetPasswordEmail.html",
    resolve: {
        tokenStatus: getTokenStatus
    }
})

Here's the getTokenStatus function that's being called for both of them:

var getTokenStatus = ["$q", "$route", "tokenService", function($q, $route, tokenService)
{    
    var deferred = $q.defer();

    var tokenType = ???? //<-- how do I pass this?

    tokenService
        .getTokenStatus($route.current.params.token, tokenType)
        .success(function(response)
        {                    
            deferred.resolve(true);
        })
        .error(function()
        {
            deferred.resolve(false);
        });

    return deferred.promise;
}];

The problem is that in order to avoid code duplication I need to somehow pass the value of the token type, as marked in the code. How could I do that?

I've been messing about with this for the last 2 hours, but can't seem to figure it out.

4
  • 1
    why you don't pass it in route itself? that would be easier Commented Feb 22, 2015 at 10:57
  • where do you get that token type? Commented Feb 22, 2015 at 11:28
  • @pankajparkar: That's the workaround I'm using now, but semantically isn't the best way. Commented Feb 22, 2015 at 11:30
  • @NitsanBaleli: I'd specify it manually, preferably in routing somehow. It's a known set of values. For example email confirmation is 0, password reset is 1. If getTokenStatus would be a normal function I'd call it like this: getTokenStatus(token, tokenType). That's what I'm trying to achieve in essence, but while I get token from the URL, I'd like to set tokenType in code. Commented Feb 22, 2015 at 11:38

2 Answers 2

5

1. You can try to include token type into route

.when("/:tokenType/:token", {
    controller: "confirmEmailController",
    templateUrl: "/app/views/confirmEmail.html",
    resolve: {
        tokenStatus: getTokenStatus
    }
})
.when("/:tokenType/:token", {
    controller: "resetPasswordController",
    templateUrl: "/app/views/resetPasswordEmail.html",
    resolve: {
        tokenStatus: getTokenStatus
    }
})

And then just get it from $route.current.params.tokenType. But it's not clean solution - you should check your URL for validity.

2. You can use function wrapping

$routeProvider.when("/confirm/:token", {
    controller: "confirmEmailController",
    templateUrl: "/app/views/confirmEmail.html",
    resolve: {
        tokenStatus: getTokenStatus("confirm")
    }
})
.when("/reset/:token", {
    controller: "resetPasswordController",
    templateUrl: "/app/views/resetPasswordEmail.html",
    resolve: {
        tokenStatus: getTokenStatus("reset")
    }
});

var getTokenStatus = function(tokenType) {
    return ["$q", "$route", "tokenService", function($q, $route, tokenService) {
        var deferred = $q.defer();
        tokenService
            .getTokenStatus($route.current.params.token, tokenType)
            .success(function(response)
            {                    
                deferred.resolve(true);
            })
            .error(function()
            {
                deferred.resolve(false);
            });
        return deferred.promise;
    }];
};

3. You can move get-token-status logic into separate servise

$routeProvider.when("/confirm/:token", {
    controller: "confirmEmailController",
    templateUrl: "/app/views/confirmEmail.html",
    resolve: {
        tokenStatus: ['tokenStatusGetterService', function(tokenStatusGetterService){
            return tokenStatusGetterService("confirm");
        }]
    }
})
.when("/reset/:token", {
    controller: "resetPasswordController",
    templateUrl: "/app/views/resetPasswordEmail.html",
    resolve: {
        tokenStatus: ['tokenStatusGetterService', function(tokenStatusGetterService){
            return tokenStatusGetterService("reset");
        }]
    }
});

//...

.service('tokenStatusGetterService', ["$q", "$route", "tokenService", function($q, $route, tokenService) {
    return function(tokenType) {
        var deferred = $q.defer();
        tokenService
            .getTokenStatus($route.current.params.token, tokenType)
            .success(function(response)
            {                    
                deferred.resolve(true);
            })
            .error(function()
            {
                deferred.resolve(false);
            });
        return deferred.promise;
    };
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

The second solution is what works best in my situation. Thanks!
1

one way to do it is to put a function on your getTokenStatus service. this is a simplified example, yet it shows how to pass an argument to your resolve function.

app.factory('getTokenStatus',['$q', '$timeout', '$route', function($q, $timeout, $route){
  this.action = function(tokenType) {
    var defer = $q.defer();

    $timeout(function(){
      var res = {
        path: $route.current.params.token,
        tokenType: tokenType
      }
      defer.resolve(res);
    },1000);

    return defer.promise;
  }

  return this;
}]);

and call it from your resolve object:

app.config(function($routeProvider){
  $routeProvider
  .when("/123/:token", {
    template: "<h1>hello</h1>",
    controller: 'testCtrl',
    resolve: {
      tokenStatus: function(getTokenStatus) {
        return getTokenStatus.action('firstToken').then(function(res){
          console.log(res);

        });
      }
    }
})

here's a plnkr

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.