AngularJs ui-router access direct trought url param - angularjs

Currently I'm building a webApp and I'd like to create a link to have direct access to a specific user, city or company. For example:
myapp.com/cityName
myapp.com/user321
myapp.com/BusinessName
I can set the proper name, id, or whatever the param is. But the problem is when I try to access this state or other page, they have conflict. For example, if I try to go to the homepage, which has this configuration:
.state('home', {
url: '/Welcome',
//..other configs
})
The router try to get the url as a param and send the user to the page of the company, user or city.
Is there a way to achieve this result?
Edit:
Currently, to avoid this conflict, I'm using my routing like this:
.state('city', {
url: '/City/:cityName',
//..other configs
})
But I'd like, if possible, to use like this:
.state('city', {
url: '/:cityName',
//..other configs
})
Because I want users to be able to access the page by typing the name direct on the url.

If I understand you correctly you probably want something like this.
.state('home', {
url: '/welcome',
//..other configs
})
.state('cities', {
url: '/cities/:parameter'
})
This way you remove the conflict.
Update: You could also make an array with excluded parameters, if the parameter is not in the excluded list, redirect to a different state.
.state('home', {
url: '/:slug',
//..other configs
})
.state('cities', {
url: '/cities/:slug'
})
var excludedWords = ['welcome', 'homepage'];
$rootScope.on('$stateChangeStart', function(event) {
if(excludedWords.indexOf($stateParams.slug) !== -1) {
event.preventDefault();
$state.go('cities', $stateParams);
}
});
This way, if a user enters /welcome, he/she won't get redirected to the /cities/welcome page, but if he/she enters /newyork he/she will be redirected to /cities/newyork

Related

angular js UI Router sending params in URL

I have a state in my config.js which looks like this:
state("link_redirect", {
url: "/link-redirect/",
controller: "LinkRedirectCtrl",
title: "Redirect Link",
params: {endpoint: null}
});
I dont want to change the state definition in shown above, still how can I send the endpoint params in URL so that I can fetch it using $stateParams service in my controller ?
There are two ways to access state params. Send as your state definition
state("link_redirect", {
url: "/link-redirect",
controller: "LinkRedirectCtrl",
title: "Redirect Link",
params: {endpoint: null}
});
Access them like, $stateParams.params.endpoint
But if you want your endpoint visible in URL, you must send like
url: "/link-redirect/:endpoint"
Remove params: {endpoint: null}
and access it like this $stateParams.endpoint

How to use $urlRouterProvider.when to change Stamplay facebook redirect URI into correct route

So I am using Stamplay facebook login. But it looks like I can not change the redirect URI. So after successfully login on facebook end, it redirect to this URI:
https://actorreels.stamplayapp.com/?jwt=[token]#/_=_
This will trigger my main route instead of the admin route - where I want user to land after login. Here is my stateProvider setting:
$stateProvider
.state('people', {
url: '/:nameUrl',
templateUrl: 'app/frontend/page.tmpl.html',
params: {
nameUrl: {squash: true},
},
controller: "PageController",
controllerAs: 'vm'
})
.state('admin', {
url:'/admin/:userId',
templateUrl:'app/frontend/admin/admin.html',
controller:'AdminController',
controllerAs: 'admin'
})
As you see, the return URI will trigger people route with nameUrl = "=". I want user to go to admin route instead with jwt as JSON token. How can I do that?
I understand there is $urlRouterProvider.when() I can use to make "/?jwt=" into my admin route. But I do not know how to do that (either in Regex or function...). Could someone help me to figure this out? Greatly appreciated!
You can change the redirect URI for Stamplay inside the editor.
First go to the editor inside the USERS > AUTHENTICATION.
Here you will see icons for all the social logins.
On the far right, you can select the cog icon to manage setting for your login flow. Here you can changed the redirect URI for login, and logout.
Note that for your angular application, include the route beginning with the #. For example. https://mystamplayapp.stamplayapp.com/ is the base url, so your need to enter #/route inside the editor to go to the "route" route.

Angular.js: page flickering on authentication redirect

I'm implementing some simple client-side authentication logic in Angular.js. The pages involved are:
/account#/login (public)
/account (require login)
/account#/settings (require login)
When a user is not logged in and try to visit either /account or /account/#/settings, the app is supposed to redirect to the login page.
I have the following routes configured using ui-router:
$stateProvider
.state('overview', {
url: '/',
restricted: true
})
.state('settings', {
url: '/settings',
restricted: true
})
.state('login', {
url: '/login',
restricted: false
})
and upon URL change, I check if the upcoming page is a restricted page and whether the current user is not logged in. If so redirect to login.
app.run(function($rootScope, $location, $state, auth) {
$rootScope.$on('$stateChangeStart', function(event, next) {
if (next.restricted && !auth.isLoggedIn()) {
event.preventDefault();
$state.go('login');
}
});
});
auth is just a service that checks the login status and returns either true (logged in) or false (not logged in).
Here's my question:
Even though this (kind of) works, I see a page flickering issue when trying to visit a restricted page while not logged in. The page flashes the contents of the restricted page quickly before redirecting me to the login page.
I did a little bit researching online and some people have mentioned the potential solution could be using resolve when defining my states, since the page won't load unless it resolves successfully. However, when I try to add
resolve: {
load: function(auth) {
return auth.isLoggedIn();
}
}
It didn't work. What am I missing? Is using resolve the way to go?
The way you are currently doing it will check if the user is logged in or not and set load to true or false. Also controller gets instantiated before load is resolved which is why you see the flickering. You need to achieve two things here:
Make sure that load is resolved before the controller is instantiated.
If user is not logged in, redirect the user to the login page.
For the first part we need to use a promise as it will be resolved and converted to value before controller is instantiated. This is what the documentation says:
If any of these dependencies are promises, they will be resolved and
converted to a value before the controller is instantiated and the
$stateChangeSuccess event is fired.
Following code can do that for us:
var isLoggedin = ['auth', '$q',
function(auth, $q) {
var deferred = $q.defer();
//assuming auth.isLoggedIn returns a promise
var loginPromise = auth.isLoggedIn();
loginPromise.then(
function(response) {
deferred.resolve(response);
},
function(error) {
deferred.reject('Not logged in');
});
return deferred.promise;
}
];
And states will use isLoggedin:
$stateProvider
.state('overview', {
url: '/',
resolve: {
loggedin: isLoggedin
}
})
.state('settings', {
url: '/settings',
resolve: {
loggedin: isLoggedin
}
})
.state('login', {
url: '/login'
})
For the second problem, that is redirecting the user to login page, you can listen to $stateChangeError event which is fired in case the state is not resolved, and use $state.go to redirect the user.

url routing with parameter in angular js

I have this routing configuration in app.js:
$stateProvider.state('home', {
url: '/',
views:
{
'contentView':
{
templateUrl:'modules/login/login.html',
controller:'loginCtrl'
}
},
data:
{
login: true
}
});
Whenever user hits the browser with URL http://.../MyClient/#/?param=ParamValue.
It will take the user to the login page and I am able to access the param value as well.
There is a logout button in the successive pages and after logout, I want to redirect to the initial URL and if I try something like
$location.path('/#/?param=ParamValue');
the user will stay on the same page and URL will be like this:
http://.../MyClient/#/%23/%3Fparam=ParamValue
Please let me know how to fix this.
You should try to use the $state service to navigate between your states, $state.go('home', {param: ParamValue})
also add the parameter you need in the url template for the state.
$stateProvider.state('home', {
url: '/?param',
views:
{ ....
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#state-1

AngularJS pass request directly to backend

I think I've missed something but I have problem with implementing for example users activation process with use of links sent to users' e-mails.
I have page for signing up. After filling form request is sent to backend where some logic is done and also mail is sent to user's mailbox. In this mail there is activation link.
And here my problem starts - I want user to click that link and be moved to my page but I want to pass this token directly to backend to check its validity, activate account and at the end redirect user to login page.
How to implement that correctly?
That's my current routing configuration for AngularJS app:
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'appController'
}).when('/login', {
templateUrl: 'views/login.html',
controller: 'userController'
}).when('/signup', {
templateUrl: 'views/signup.html',
controller: 'userController'
}).when('/activate/:activationToken', {
templateUrl: 'views/activate.html',
controller: 'userController'
}).otherwise({
redirectTo: '/'
});
That's my current backend routing configuration for node.js:
router.post('/users/login', userHelper.shouldNotBeLoggedIn, authentication.login);
router.post('/users/signup', userHelper.shouldNotBeLoggedIn, authentication.signup);
router.get('/users/logout', userHelper.shouldBeLoggedIn, authentication.logout);
router.get('/users/activate/:token', userHelper.shouldNotBeLoggedIn, authentication.activate);
Here is how I return data from backend to frontend:
if (err) {
logger.error(util.inspect(err));
res.status(403).json({message: err.code});
} else {
res.status(200).json({message: 'accountActivated'});
}
One way is to use a pure back-end URL + view that handles the account activation if the token is correct, then 302 redirect to a regular URL where the Angular app lives. If the token is incorrect, redirect to a URL that displays an error message.
Update:
In userController, when the URL matches the URL sent in the activation email (this may already exist at /activate/:activationToken), sent the token to your back-end like this:
// Make sure to inject $http and $routeParams in your controller.
$http.post('/users/activate/' + $routeParams.activationToken, {}).success(function(response) {
console.log('Yay');
}).error(function(response) {
console.error(response.data.message)
});

Resources