Accessing a property from a service in a template - ember.js

I have a user service that manages reading data from localstorage, it has a property that reads from the local storage a certain object property, the service is setup like so
import Ember from 'ember';
import LocalUser from 'bidr/models/user-local';
const {
computed: {
alias
}
} = Ember;
export default Ember.Service.extend({
localUser: LocalUser.create(),
user_id: alias('localUser.user.id'),
active_auction: alias('localUser.user.active_auction')
});
In my route.js file for my item route I inject the service like so
user: Ember.inject.service('user'),
And in the template I'm attempting to access it like so
{{user.active_auction}}
I was under the impression I could do that but is that not the case? Do I need to set a property on the item route that is equal to the service property to make this work?

If you don't want to create a controller for this template's scope, you can expose the service to the template by setting a property in the auto-generated controller via the route's setupController hook, like so:
// application/some-route.js
export default Route.extend({
user: service(),
setupController(controller, model) {
this._super(controller, model);
set(controller, 'user', get(this, user))
}
});

Related

set alias for `model` hook

HELP
If there is a model hook in app/routes/post.js say
model() {
return this.store.query('post');
}
in template the returned promised is accessed using
{{#each model as |post|}}
...
{{/each}}
Is there any way to set alias for the model? Something like this in route or controller?
posts: alias('model')
So I can access the returned promise in the template as
{{#each posts as |post|}}
...
{{/each}}
Is this something which is already present or something that got missed from ember documentation?
you can create alias for model property in your controller,
import Controller from '#ember/controller';
import { alias } from '#ember/object/computed';
export default Controller.extend({
posts: alias('model')
})
or using setupController in your route,
export default Route.extend({
setupController(controller, model) {
controller.set('posts', model);
},
});
Reference:
alias api documentation - alias computed property
alias your model - alias-model-rule

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

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.