Ember output vars form other controllers / models in a view - ember.js

I think i have a fundamental problem of understanding how to access vars in a View form other controllers.
I read the Ember-Documentation many times and "hundreds" of Blog-Entries, but i did not find a solution.
After Submitting a Loginform, i want to set the var "isLoggedIn" from Auth Controller / Model and output it in the Login View. Auth will be used later from many other Components, thats why i want to separete it from Login.
Here is a small part of my code:
Template: Login
Authenticated: {{controllers.auth.isLoggedIn}} <--- after Login this should be TRUE, but how ?
...LoginForm: here is the login form with input fields (email and password)...
Controller: Login
var LoginController = Ember.Controller.extend({
needs: "auth",
// LoginForm Submit-Event
login: function() {
App.Login.createRecord(this.getProperties("email", "password"));
DS.defaultStore.commit(); // on server respond, id of model.login is changed, see "idObserver"
}
});
Model: Login
var Login = DS.Model.extend({
email : DS.attr("string"),
password : DS.attr("string"),
// Because of Ember Bug i have to use idObserver after "DS.defaultStore.commit()"
// to get the ID responded from the server.
idObserver: function() {
var auth = App.Auth.create();
auth.set("id", this.get("id"));
}.observes("id")
});
Controller: Auth
var AuthController = Ember.Controller.extend({
isLoggedIn: false // What should i write here to connect to isLoggedIn of Auth.Model ???
}); // Controller
Model: Auth
var Auth = Ember.Object.extend({
isLoggedIn: DS.attr("boolean"),
idObserver: function() {
if(this.get("id")) this.set("isLoggedIn", true);
else this.set("isLoggedIn", false);
}.observes("id")
});
How can i output "controllers.auth.isLoggedIn" in the Login Template ?

Normally the instance of the auth model would be set on the content property of your auth controller (typically handled by the router). Once the content is set then your template would work with no modifications.
This gist might help you out as it as a login example using the router:
https://gist.github.com/machty/5647589

Related

Ember.js : Modify request URL

I create an Ember app with a Symfony REST api. I also use the REST adapter for my requests.
I have 2 models in my app : users and their related comments.
I already created CRUD operations for my user properties and now I focus on the CRUD operations for comments.
Model user.js
export default DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
comments: DS.hasMany('comment')
});
Model comment.js
export default DS.Model.extend({
title: DS.attr('string'),
message: DS.attr('string'),
user: DS.belongsTo('user')
});
I have a route which shows all comments (and other data) of a given user. The request loads the user object and his relations. On the view I also have a form and an action to create a new comment for this user.
Route users/get.js
import Ember from 'ember';
export default Ember.Route.extend({
id: null,
model(params) {
this.set('id', params.user_id);
return this.get('store').findRecord('user', params.user_id, {include: 'comments'});
},
});
Route users/get/comments.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.modelFor('user.get', params.user_id);
},
});
Controller users/get/comments.js
import Ember from 'ember';
export default Ember.Controller.extend({
newComment: null,
user: null,
init: function() {
this._super(...arguments);
let comment = this.store.createRecord('comment');
this.set('newComment', comment);
},
actions: {
saveComment: function() {
let user = this.get('model');
let comment = this.get('newComment');
comment.set('user', user);
comment.save();
}
}
});
Everything works, except for the request sent to the backend. I loaded the comments from the user, so I expect a call to :
POST http://my-app.local/users/comments/
Instead the call is sent to :
POST http://my-app.local/comments/
Do you know why and how could I correct it ?
Second problem, the model is loaded from the 'user.get' route. This works because the user comes from this route to this page, but... It's doesn't work if the user enters directly the URL for comments. That sound logical, but I have no clue how to correct this problem... Can you help me ?
This can be done by rewrite the CommentAdapter.urlForCreateRecord method. Which affect new comment record requests.
adapters/comment.js
import DS from 'ember-data';
export default DS.RESTAdapter.extend({
urlForCreateRecord(modelName, snapshot) {
return '/users/comments'; // the url you want
}
});
There are several urlFor... method you might need to customise your url.
Just check out the document
http://devdocs.io/ember/classes/ds.buildurlmixin/methods#urlForCreateRecord

Emberjs route is unable to access authenticated user

My Ember app will show user's information after they are authenticated. I am doing authentication with Firebase and the user the is being authenticated, but the route seems to trying to find the user before this happens. It gives me this error:
Assertion Failed: You cannot pass `undefined` as id to the store's find method
Any idea how to fix this/ why it is happening?
Here is my application route with the login function:
login: function(email, password) {
this.get('session').open('firebase', {
provider: 'password',
email: email,
password: password
}).then(function() {
this.transitionTo('index');
}.bind(this));
},
logout: function() {
this.get('session').close().then(function() {
this.transitionTo('application');
}.bind(this));
}
Here is my index route:
model: function(params){
return this.store.find('user', params.user_id);
}

Best way to get Current User session in Ember with Torii

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/

How can I use ember-simple-auth to set header in custom url api with ember data?

My ember data model:
import DS from 'ember-data';
import config from './../config/environment';
export default DS.Model.extend({
...
useRepairPackage(repairPackageId) {
this.get('session').authorize('authorizer:digest', (headerName, headerValue)=> {
const headers = {};
headers[headerName] = headerValue;
Ember.$.ajax({url: `${config.host}/${config.namespace}/quotations/${this.get('id')}/use_repair_package.json`, type: "PATCH", headers: headers}).then((result)=> {
return this.reload();
});
});
}
});
I check ember-simple-auth document, I found this way to add session in header. But it can not work in model, and how can I add the seesion in this action? Thanks.
You can expose the session service to the model and then access it.
export default DS.Model.extend({
session: Ember.inject.service('session'),
And now access the session below inside to send the session data.

Not able to share dependencies on a controller

I have an application running with Ember 1.12.0. I have a simple template called /app/templates/repositories.hbs with this content :
{{controllers.user.login}}
I added this in the controller app/controllers/repositories.js :
import Ember from 'ember';
export default Ember.ArrayController.extend({
needs: "user",
});
I have this route :
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
var user = this.modelFor('user');
console.log(user);
return Ember.$.getJSON('https://api.github.com/users/'+user.login+'/repos');
}
});
And this router :
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('index', {path: '/'} );
this.resource('user', {path: '/users/:login'}, function() {
this.resource('repositories');
});
});
export default Router;
According to the documentation. I should show the user login but I have just nothing. It show the user object in the console but not in the view.
Is the a solution ?
If I understand correctly, you have a user model fetched in user route (as you can see it in console, the modelFor works properly). However, you are trying to get login object on user controller - I think that it's not defined. What you really want to get is login property of the object that is the model for user route (probably it's the user, but you didn't posted your user route code).
To use these two models in one controller you don't need to share these controllers. All you need is the model for user route. Thus, you can leave your model hook as follows:
model: function(params) {
return Ember.$.getJSON('https://api.github.com/users/'+user.login+'/repos');
}
And write your setupController method as follows:
setupController: function(controller, model) {
controller.set("model", model);
controller.set("user", this.modelFor("user");
}
And in your template you would have your repos from AJAX and the user property with that property.
{{user.login}}
On the other hand, you could, with some fixes, use the shared user controller obtaining same effect, but it's not what you need - you need only the model for that controller, not the whole object.