How can I model singletons without an id in ember? - ember.js

I am new to ember and am trying to migrate an existing application, and would like to know what the recommendation is for modeling a single object that will be reused in multiple components on every page. ie: As part of the initial load, I would like to perform a GET request against a URL like 'https://example.com/currentUser' and get an object back like:
{
name: "Users Name"
email: "user#email.com",
profileImg: "http://example.com/pictureOfUser.png"
... snip ...
}
This object will then be used in components for menus, toolbars, and a form for updating it via a post to the same URL.
What is the best way to model this workflow in ember? Given that this is an incidental object and not the focus of most routes, it does not seem to make sense to specify it as the model of them. Also, does ember data handle cases where a model is a singleton and does not have an ID, or would I need to use something like Ember.$.ajax ?

What do you mean by "where a model is a singleton"?
If you use the ember-data default adapter, then yes, a model needs to have an ID, it's part of the JSONAPI spec. If you already have a backend with different conventions, take a look at extending or swapping out the default adapter.
A service is a singleton, and there is nothing preventing you from making an AJAX call there. You would be losing out on all the nice things that come along with ember-data, but, you can do it.

Related

Ember-Data: Adding Server Queries to AJAX Requests

I am having trouble with a specific case using Ember-Data.
Typically Ember expects a model class, the route, the ajax request, and the returned JSON, to all follow a similar pattern.
The RESTAdapter tries to automatically build a URL to send to the server, which is ok for some situations, but I need full control over some of my request URLs particularly when it comes to appending additional parameters, or matching an API to a route that has a completely different URL structure.
Ember sadly, has no guides for this, though I did find something about the buildURL method
I am not comfortable enough rooting through the source code to find out what happens under the hood though I do not want to break ember data just to fix a few use cases.
I have set my RESTAdapter's namespace to api/rest
The model and resource I want to populate is view-debtors
The specific service I want to reach is at debtor/list
I also need to pass extra parameters for pagination ?page_size=10&page_number=1, for example.
I am completely lost how to do this. I cannot change the API structure... there are too many services depending on them.
Some Small Progress
I went ahead and used my current knowledge to get a little closer to the solution.
I created a model and called it "list"
I extended RESTAdapter for "list" to change the namespace to "api/rest/debtor"
I changed the model hook for "view-debtors" route to store.find('list')
The result now is that the AJAX call is almost correct... I just need to add those extra parameters to the server queries.
This is where I stand now... can I add those server queries via the model hook? or better yet can I also control server queries via ember actions to get new AJAX requests?
Stepping back a bit. Is my method so far a good practice? Because I am using a route's model hook, to set the model to list, will this only work if the routes URL is typed in directly?
So many questions :p
You can find by query which will append a query string onto the end of your request using the object provided.
// this would produce /api/rest/debtor/lists?page_size=1&page_number=10
this.store.find('list', {page_size:1, page_number:10});
Personally I think it's a bit hacky to go fudging the model names and namespace to make it supposedly fit your backend's url structure. It really depends on what you're attempting to do. If you want all the full features of CRUD using Ember-Data for this particular list of data, you're going to be hacking the end-point left and right. Whether or not Ember Data really helps you is questionable. If you are just reading data, I'd totally just fetch the data using jquery and sideload it into Ember Data.
var store = this.store;
$.getJSON('/api/rest/debtor/lists?page_size=1&page_number=10').then(function(json){
//fix payload up if necessary http://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload
store.pushPayload('type', json);
}).then(function(){
return store.all('type'); // or store.filter('type') if you want to filter what is returned to the model hook
});
pushPayload docs

EmberJS view components and separate data store

I'm looking at creating a google maps component. But I would like it to be self contained so it will have its own model, controllers and views. So for example the component will fetch its own data from the server and I'll also be able to refresh the data when needed. Ideally I'd simply add the component to the current template that is showing, so for example: {{map-view}} and then everything the component needs to do will take care of its self.
The component will also need to listen to triggered events from other controllers as a user will be able to search for a specific location and the map will need to change its position.
Is this possible to do in EmberJS? As I haven't found anything like this, specially when having its own model. I know there is a component in EmberJS but it seems very limited. Am I wrong in thinking this?
the controller cannot have its own model all values must be passed to component. Please refer to ember docs and this Discussion
You can make a google map component and pass the location and marker data to the component. this data will get updated due to ember data binding.
so you can have something like this
{{map-view location=userEnteredValue}}
you can search for ember component talk by Kris Selden on youtube which includes a google map component good for you to start with.
updated
https://gist.github.com/krisselden/8189650

get all bindings of templete in ember

Is there a way to get all bindings of all fields or checkboxes of a template in ember ?
The intention is to get them in a generic way, to store them in a generic way in a json object and to send them to the server. The server maps the variable names to the model attributes. Something like I call a function from the controller with the template name and get back all bindings ?
get_bindings("templatename":"test_template")
How should this method look like ?
This is really the purpose of two-way bindings in Ember. When you have an object that looks like...
person = Ember.Object.create({
name: 'Jane',
age: 25
});
and a template that looks like...
<div>Enter your name here: {{input value=person.name}}</div>
<div>Enter your age here: {{input value=person.age}}</div>
...then when you type something new in the boxes, your person object automatically gets updated. To persist your person, all you have to do is serialize the person object and send it off to the server. There's no asking the template for the new values or manually synchronizing the two.
If you are looking for a more sophisticated way of managing local model lifecycle and interacting with a server that follows certain JSON conventions, check out Ember Data or any of the other maturing data persistence libraries that are popping up.
Ember doesn't give you a way to easily interact with the view from the controller by design.

Where to save detailed user session information for EmberJS app?

I am building my first EmberJS app, and am still trying to wrap my head around the best practices & conventions. I'm using ember-data to talk to a RESTful API, and have ember-auth working well enough to log in and save a user's ID & OAuth2 access token. However, I'd now like to maintain additional user information (e.g. name, email, etc) for use in the navbar and in various other areas of the app.
To do this, I am thinking it would be helpful to have a User object (model) that is read from a separate endpoint (e.g. /users/<id>). Since this info would be needed throughout the app, I'm inclined to store it on the ApplicationController, somewhat like this example from Ember's docs:
App.ApplicationController = Ember.Controller.extend({
// the initial value of the `search` property
search: '',
query: function() {
// the current value of the text field
var query = this.get('search');
this.transitionToRoute('search', { query: query });
}
});
However, my user object wouldn't quite be an action like query or a property like search, so I'm not sure this example applies.
I think I'll eventually want to call something like:
this.get('store').find('user', App.Auth.get('userId'));
but I'm just not sure where in the app that would go.
Main question: is the ApplicationController the right place for this information per Ember conventions, and if so, what might the code look like to retrieve it from the REST API?
Appreciate any thoughts to put me on the right track.
The general approach that I've taken before is to store the currently logged in user as App.CurrentUser. Then you can use it in any template. Once I've pulled the User object I call Ember.set('App.CurrentUser',user) to store it, and then Ember.get('App.CurrentUser') to retrieve it in other routes or controllers.
Here's a short jsbin with the general idea : http://jsbin.com/ucanam/994/edit

What type of controller should I use to represent a complex object which is not a (persisting) model?

I'm writing a calendar application, which will need to display events by month.
While I'll need to create objects to represent the calendar months, I take it that these these CalenderMonth objects should NOT be 'models' (in Ember terminology), since the CalendarMonth objects won't persist to the server (whereas the Event objects will). Instead, the CalendarMonths will be 'objects', build with a CalendarMonth 'class', extending Ember.Object
So then, what sort of controller do I use as a proxy to the (frequently changing) CalendarMonth object? A (vanilla) controller? An ObjectController? An ArrayController?
ObjectController seems like the way to go, since it really is my intention for the the controller to act as proxy to a single object. I think I'm only thrown by the fact that in the corresponding route object, I'd be assigning the CalendarMonth object as the controller's MODEL. When, it's not a model, it's just an object.
Put another way, my question is:
Is it bad practice to assign an Ember object which is NOT a model to an ObjectController's 'model' property?
It is not bad practice to use a normal JS object as a controller's model/content. All that matters is how the view is going to render the model. If you're only going to display a single event at a time, or a single month for all events in that month, then the ObjectController is your best bet.
An ArrayController is used for when you want to loop round your model/content in the controller and display each item in the view. I don't think you should worry too much about what controller you should use, it will become pretty obvious which one you want as soon as you decide how to create your view.
When Ember talks about using a Model for your controller, you can use your own Ember Object if you wish and then reference it in the controller, but it doesn't matter if that is a natural JS object or Ember Object. A controller sees both just fine.