Following on from this question I am trying to set both the currentUser and the account properties in my custom session:
/app/sessions/custom.js
import Ember from 'ember';
import Session from 'simple-auth/session';
export default Session.extend({
currentUser: Ember.computed('secure.user_id', 'isAuthenticated', function() {
console.log('currentUser');
var userId = this.get('secure.user_id');
if (userId && this.get('isAuthenticated')) {
return this._store.find('user', userId);
}
}),
account: Ember.computed('currentUser', function() {
console.log('account');
this.get('currentUser').then(function(currentUser) {
return this._store.find('account', currentUser.get('account').id);
})
})
});
but for some reason the console.log('account'); is never called. I guess that this is because currentUser is a promise and thus hasn't yet resolved?
Should I return an Ember.RSVP.hash instead?
Related
Let, I have two routes and two controllers namely login and signup
If I signup successfully then I want to perform transition to the route login with a success message as parameter,
/app/signup/controller.js
import Controller from '#ember/controller';
export default Controller.extend({
actions: {
signup: function(){
let _this = this;
let successMessage = 'successfully registered';
var credentials = this.getProperties('name','identification','password');
let list = this.store.createRecord('user', {
name: credentials.name,
email: credentials.identification,
password: credentials.password
});
list.save().then(function(){
_this.transitionToRoute('login','successMessage');
});
}
}
});
app/login/template.hbs
<body>
{{successMessage}}
</body>
/app/router.js
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('login');
this.route('signup');
});
export default Router;
I think you sort of have 3 options:
Use a route param (query param or positional)
Use a service to manage login stuff, and read some computed property from the service representing your state / message from your login controller
Use a flash/toast style UI where the message lives outside of the app view/component hierarchy
Personally, for where you want to display your message, I'd go for #2, which would look like this:
// app/services/user-session.js
import Service from '#ember/service';
export default class extends Service {
successMessage = null;
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
}
// app/controllers/signup.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { action } from '#ember-decorators/object';
export default class extends Controller {
#service userSession;
#action
signup() {
this.userSession.signup(...);
this.transition...
}
}
// app/controllers/login.js
import Controller from '#ember/controller';
import { service } from '#ember-decorators/service';
import { readOnly } from '#ember-decorators/object/computed';
export default class extends Controller {
#service userSession;
#readOnly('userSession.successMessage') successMessage;
}
Or, in the old syntax:
// app/services/user-session.js
import Service from '#ember/service';
export default Service.extend({
successMessage: null,
signup(name, id, password) {
// logic
this.set('successMessage', 'yay');
}
});
// app/controllers/signup.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
export default Controller.extend({
userSession: service(),
actions: {
signup() {
this.userSession.signup(...);
this.transition...
}
}
});
// app/controllers/login.js
import Controller from '#ember/controller';
import { inject as service } from '#ember/service';
import { readOnly } from '#ember/object/computed';
export default Controller.extend({
userSession: service(),
successMessage: readOnly('userSession.successMessage')
});
hope this helps
I need to get current user when a session is authenticated. I have implemented the service currentUser
import Ember from 'ember';
const { inject: { service }, isEmpty, RSVP } = Ember;
export default Ember.Service.extend({
store: service(),
user: null,
load() {
return this.get('store').find('user', 'me').then((user) => {
this.set('user', user);
});
}
});
And I call it in route/application.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin, {
session: Ember.inject.service(),
currentUser: Ember.inject.service(),
init: function(){
return this._super();
},
actions: {
invalidateSession() {
this.get('session').invalidate();
}
},
sessionAuthenticated() {
alert("sessionAuthenticated");
this._super(...arguments);
this._loadCurrentUser().catch(() => this.get('session').invalidate());
},
_loadCurrentUser() {
return this.get('currentUser').load();
}
});
When a user login or signup, the event authenticationSucceeded is called but when the session is restored in my authenticator, the event is not called. I need to call it because I need to reload user information.
I don't think that the sessionAuthenticated is triggered on restore. You need to load the user in your beforeModel hook.
// ...
beforeModel() {
return this._loadCurrentUser();
}
// ...
You can take a look at the official docs for setting the current user here
this is my controller code
controllers/new-user.js
import Ember from 'ember';
export default Ember.ObjectController.extend({
actions:{
register:function(){
var person=this.store.createRecord('person'{
firstName:fname,
lastName:sname,
email:email,
password:password,
confirmPassword:confirmPassword
});
person.save();
}
}
});
I am working with ember-cli and i am new to ember so could you please tell me what is wrong in the code.
First there is to notice you should not use Ember.ObjectController but directly extend Ember.Controller. Checkout the deprecation.
Next all your variables fname, sname and so on are not declared. Probably you want to access the attributes on the controller. So either do this:
import Ember from 'ember';
const {get} = Ember;
export default Ember.ObjectController.extend({
actions: {
register(){
let person = this.store.createRecord('person', {
firstName:get(this, 'fname'),
lastName:get(this, 'sname'),
email:get(this, 'email'),
password:get(this, 'password'),
confirmPassword:get(this, 'confirmPassword')
});
person.save();
}
}
});
Or use .getProperties:
import Ember from 'ember';
const {get} = Ember;
export default Ember.ObjectController.extend({
actions: {
register(){
let person = this.store.createRecord('person', this.getProperties(
'fname',
'sname',
'email',
'password',
'confirmPassword'
));
person.save();
}
}
});
However my personal recommendation is to call createRecord in the model hook of the route and then directly bound your template to your model. Later just call .save() in your action.
I would like to know what the best way is to get the User Model Record of the current logged in user. I'm using torii in combination with corresponding firebase adapter.
app/torri-adapters/application.js
import Ember from 'ember';
import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';
export default ToriiFirebaseAdapter.extend({
firebase: Ember.inject.service()
});
For example: I have a client model and at this moment i have this very ugly solution to query all client records associated with the current logged in user:
app/routes/clients.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var _this = this;
return this.store.query('user', {
orderBy: 'email',
equalTo: this.get('session.currentUser.email')
}).then(function(user) {
var myUser = user.get('firstObject');
return _this.store.query('client', {
orderBy: 'user',
equalTo: myUser.id
}).then(function(client) {
return client;
});
});
}
});
For sure there is a better way to do this?
You could inject the currentUser into all your controllers, routes and components at the app initialization, so you will be able to refer to the current user simply by doing this.get('currentUser') wherever you need it. See the section which shows an example of how this is done here: https://guides.emberjs.com/v2.5.0/applications/dependency-injection/
Is there a way in Ember to send cookies with the requests to the backend?
For example: if my client URL is protocol://example.com. The cookies that belong to the same domain will be in the request header when I navigate to protocol://example.com/profile. However, they do not persist in the subsequent request/s the profile route model method makes -> example to protocol://example-host/posts. How do I make those cookies persist?
/app/routes/profile.js:
import Ember from "ember";
import AuthenticatedRouteMixin from "simple-auth/mixins/authenticated-route-mixin";
export default Ember.Route.extend({
model() {
return this.store.findAll("post");
},
renderTemplate() {
this.render("header", {
outlet: "header"
});
this.render("profile");
}
});
/app/adapters/application:
import Ember from "ember";
import DS from "ember-data";
export default DS.RESTAdapter.extend({
host: 'http://example-host.com',
corsWithCredentials: true,
crossDomain: true,
xhrFields: { withCredentials: true }
});
This works in my production app. Code in app/adapters/application.js:
import Ember from 'ember';
$.ajaxSetup({
xhrFields: {
withCredentials: true
}
});
export default DS.RESTAdapter.extend({
ajax(url, method, hash) {
hash = hash || {};
hash.crossDomain = true;
hash.xhrFields = {
withCredentials: true
};
return this._super(url, method, hash);
}
})
You can also set individual header values to be sent with each ember-data request. Useful if you need to pass an API key with all your requests.
In your adapter (app/adapters/application.js):
import DS from 'ember-data';
import { get } from '#ember/object';
import { computed } from '#ember/object';
export default DS.RESTAdapter.extend({
headers: computed(function() {
return {
'API_KEY': get(document.cookie.match(/apiKey\=([^;]*)/), '1'),
'ANOTHER_HEADER': 'Some header value'
};
}).volatile()
});