I'm trying to put authentication on one of my routes with onEnter. I have the following code:
my route:
<Route path="/needauth" component={AuthComp} onEnter={validate}></Route>
my validate function:
function validate(nextState, transition, callback){
var isLoggedIn = yield asyncfunc(); // say that i called an async function here and stored the result in isLoggedIn
if(!isLoggedIn){
transition.to('/login');
}
callback();
});
}
When I try to access the route directly though, I get the following error:
Uncaught (in promise) TypeError: Cannot read property 'pathname' of null
at Object.shouldUpdateScrollPosition (webpack:///./~/react-router/lib/ScrollManagementMixin.js?:32:41)
at componentDidUpdate (webpack:///./~/react-router/lib/ScrollManagementMixin.js?:73:37)
at CallbackQueue.assign.notifyAll (webpack:///./~/react/lib/CallbackQueue.js?:68:22)
at ReactReconcileTransaction.ON_DOM_READY_QUEUEING.close (webpack:///./~/react/lib/ReactReconcileTransaction.js?:81:26)
at ReactReconcileTransaction.Mixin.closeAll (webpack:///./~/react/lib/Transaction.js?:207:25)
at ReactReconcileTransaction.Mixin.perform (webpack:///./~/react/lib/Transaction.js?:148:16)
at ReactUpdatesFlushTransaction.Mixin.perform (webpack:///./~/react/lib/Transaction.js?:134:20)
at ReactUpdatesFlushTransaction.assign.perform (webpack:///./~/react/lib/ReactUpdates.js?:95:38)
at Object.flushBatchedUpdates (webpack:///./~/react/lib/ReactUpdates.js?:175:19)
at Object.ReactPerf.measure.wrapper [as flushBatchedUpdates] (webpack:///./~/react/lib/ReactPerf.js?:70:21)
That's not how async functions work... You can only await from inside of an async function anyway.
Maybe you could try making validate an async function and calling callback once you're finished? (Or just do the check and call callback once asyncfunc is done...)
@cesarandreu I know that's not how async functions work lol. If you look at my comment you can see that I'm just saying make the assumption. Using co.js it would look something like this:
function validate(nextState, transition, callback){
co(function*(){
var isLoggedIn = yield asyncfunc();
if(!isLoggedIn){
transition.to('/login');
}
callback();
});
}
The code above is making an async call using generators and calling callback when its done.
If I don't have the async function there then no error is thrown. However, if there is an async function in onEnter, react-router seems to be trying to access a previous state (that doesn't exist because its the first time loading) and update the scroll position which throws an error because "shouldUpdateScrollPosition" on the ScrollManagementMixin expects the previous state and next state.
@juhaelee Great catch. Care to make a PR?
I don't got errors when I use an async request, but the transition is not running, I am using es6 Promises, my code looks like:
requireAuth: function(nextState, transition) {
auth.loggedIn().then(function(loggedIn) {
if (!loggedIn) transition.to('/login');
});
}
auth.loggedIn() return a promise
@individuo7 You need to do this:
requireAuth: function(nextState, transition, callback) {
auth.loggedIn().then(function(loggedIn) {
if (!loggedIn) transition.to('/login');
callback();
});
}
thanks it worked!
I can't reproduce this on master now that we're built on the history api, please let me know if you still have problems.
Is it possible to make async request in onEnter with version 1.0.0 ? In docs I see that right now the onEnter takes only two params: nextState, replaceState. No callback any more.
---- edit
Seems like docs is not correct (https://github.com/rackt/react-router/blob/d49199e4b939a01f1e9f18188166a8f8a9f52a5b/docs/API.md). In fact there is third param for onEnter.
--- edit
My fault. I was looking on outdated version of docs.
I realize this issue is closed but just to avoid confusion (I lost an hour or so after reading this issue and looking at the old docs linked above):
Most helpful comment
I realize this issue is closed but just to avoid confusion (I lost an hour or so after reading this issue and looking at the old docs linked above):
https://github.com/rackt/react-router/blob/master/docs/API.md#onenternextstate-replacestate-callback