Reputation: 1571
In my App's localStorage
I have stored a token for auth. If the user makes a full reload I need to make a request to the backend to verify this token and to get the username. For all this session stuff I have made an ember service.
My application route looks like this:
import Ember from 'ember';
export default Ember.Route.extend({
currentSession: Ember.inject.service(),
beforeModel: function(transition) {
if (transition.targetName !== 'login') {
const session = this.get('currentSession');
if (!session.isLoggedIn) {
this.transitionTo('login');
}
}
}
});
On reload the beforeModel
method on the application route is triggered, and I can get the isLoggedIn
property from the service.
In the service I have a initializeService
method which is called on init:
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
username: '',
isLoggedIn: false,
initializeService: function() {
const token = localStorage.getItem('Token');
if (token) {
const self = this;
this.get('store').findRecord('session', token).then(function(session) {
self.set('username', session.get('username'));
self.set('isLoggedIn', true);
});
}
}.on('init'),
});
This works basically, but there is a race condition because of the async request findReocord
. initializeService
is not called until this.get('currentSession');
in beforeModel
, and while the service is requesting the backend, beforeModel
continues. So the if (!session.isLoggedIn)
is always true.
I tried to initialize the service earlier by using an instance-initializer but that didn't work either. I think I need to make some kind of a synchronous findRecord
.
Is there a possibility to do a request synchronous or is there a better way?
Upvotes: 2
Views: 360
Reputation: 12872
Introduce method named loadCurrentUser
in current-session service which returns Promise and in beforeModel
use then
method to implement your logic.
Sample Code, current-session.js service file
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service(),
username: '',
isLoggedIn: false,
init() {
this._super(...arguments);
this.loadCurrentUser(); //if you are not calling loadCurrentUser method then this will ensure username and isLoggedIn set properly
},
loadCurrentUser() {
return new RSVP.Promise((resolve, reject) => {
const token = localStorage.getItem('Token');
if (!isEmpty(token)) {
return this.get('store').findRecord('session', token).then((session) => {
this.set('username', session.get('username'));
this.set('isLoggedIn', true);
resolve();
}, reject);
} else {
resolve();
}
});
}
});
application.js route file
import Ember from 'ember';
export default Ember.Route.extend({
currentSession: Ember.inject.service(),
beforeModel: function(transition){
return this.get('currentSession').loadCurrentUser().then((result) => {
if (transition.targetName !== 'login') {
const session = this.get('currentSession');
if (!session.isLoggedIn) {
this.transitionTo('login');
}
}
}
},
});
Upvotes: 1