In my Rails API I am using JSONAPI structure which Ember expects by default.
I have a Rails route http://localhost:3000/profile
which will return the currently logged in user JSON.
How do I make an arbitary request to this /profile
endpoint in Emberjs so I can get my logged in user's JSON in my router's model() hook?
I tried following this guide here:
https://guides.emberjs.com/v2.10.0/models/finding-records/
And have this code:
return this.get('store').query('user', {
filter: {
email: 'jim@gmail.com'
}
}).then(function(users) {
return users.get("firstObject");
});
It is returning the incorrect user however. It also seems like it doesn't matter what the value of 'email' is, I can pass it 'mud' and it will return all users in my database.
Is there no way for me to make a simple GET request to /profile in my model() hook of my profile route in Ember?
It has come to my attention that the filter thing in Ember is actually just appending a query parameter onto the end of the request URL.
So having my above filter, it would be like making a request:
GET http://localhost:3000/users?filter['email']=jim@gmail.com
Which doesn't help because my Rails doesn't know anything about filter query parameter.
I was hoping Ember will automatically find the user and do some black magic to filter the user to match email address for me, not me having to manually build extra logic in my Rails API to find a single record.
Hurrmmmmmmm...sure feels like I'm fighting against the conventions of Ember at the moment.
Thanks to Lux, I finally got it working with the following approach:
Step 1 - Generate the User adapter:
ember generate adapter user
Step 2 - write the AJAX request in the queryRecord method override for User adapter
import ApplicationAdapter from './application';
import Ember from 'ember';
export default ApplicationAdapter.extend({
apiManager: Ember.inject.service(),
queryRecord: function(store, type, query) {
if(query.profile) {
return Ember.RSVP.resolve(
Ember.$.ajax({
type: "GET",
url: this.get('apiManager').requestURL('profile'),
dataType: 'json',
headers: {"Authorization": "Bearer " + localStorage.jwt}
})
);
}
}
});
Step 3 - make the model()
hook request like so:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').queryRecord('user', {profile: true});
}
});
Well, query
is for server side filtering. If you want it client-side use something like store.findAll('user').then(users => users.findBy('email', 'bla@bla.bla'));
.
But this is not what you want. You have your server side filter. It's just under /profile
. Not under /user
.
However interesting is what /profile
actually responds. A single-record-response or a multi-record-response. The best would probably a single-record-response since you only want to return one user. So how can we do this with ember? Well, we use store.queryRecord()
.
And because ember does not know anything about /profile
we have to tell it ember in the user
-adapter with something like this:
queryRecord: function(store, type, query) {
if(query.profile) {
return Ember.RSVP.resolve(Ember.$.getJSON('/profile'));
}
}
And then you can just return store.queryRecord('user', { profile: true })