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

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.

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

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/

Requests to different backend endpoint from same route and save the result in different model

I have a designed a app in ember.Now the app has feed page similar to fb and instagram.Now to get the username and his display pic, I have to send the request to "http://example.com/api/users/profile/?targetuser=-1" and the to get the user feed I have to make the requests to "http://example.com/api/feed".I am not able to figure out how to do it.
routes.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin,{
model(){
return Ember.$.ajax({
url: 'http://example.com/api/users/profile/?targetuser=-1',
headers:{
"Authorization":"token b0"
},
success:function(user_details)
{
console.log(user_details.full_name);
}
});
},
model(){
var inflector = Ember.Inflector.inflector;
inflector.uncountable('feed');
return this.store.findRecord('feed');
}
});
But in this case request is made only to "http://example.com/api/feed" and the ajax call is left.
I also want to store the data from both call to different store ,So that I can use it in hbs.
my models
feed.js
import DS from 'ember-data';
export default DS.Model.extend({
FeedResult: DS.attr(),
// gallery_name:DS.attr(),
// feedPhotos:DS.attr()
});
profile.js
import DS from 'ember-data';
export default DS.Model.extend({
results: DS.attr(),
photos:DS.attr()
});
Please suggest how should I do this so I can display the username,display pic and his feed on same page just like fb and instagram.

Accessing a property from a service in a template

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))
}
});

How do I get cookies to to be sent with my requests to the backend in ember app?

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()
});