EmberJS view components and separate data store - ember.js

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

Related

How can I model singletons without an id in ember?

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.

How do I structure an Ember.js app so I can access application state from itemControllers?

I have a collection of models, each of which stores a bit of application-persistent state on the controller. I want to access this state elsewhere in the app, but I'm not sure exactly how.
Here's a JS Bin with a stripped-down version of the app which demonstrates what I'm trying to do: On the "Boxes" route, I want to display a count of the number of clicked widgets, but from BoxController I don't know how to get access to the WidgetControllers that have that property.
If I understand the guides correctly, I should be able to use needs to inject one controller into another, but this doesn't really apply when I'm using itemController to wrap each model in its own controller instance.
I would break it up into 3 parts...
1) Add a computed property to the App.WidgetsController the contains the checked widgets. Something like
clickedWidgets: Ember.computed.filterBy('#this', 'hasBeenClicked', true)
2) Add needs: ['widgets'] to the App.BoxController
3) Change the clickedWidgets computed property of the App.BoxController to get the list of clickedWidgets from the App.WidgetsController and the filter that list by widgets which match the box.
clickedWidgets: function() {
return this.get('controllers.widgets.clickedWidgets')
.filterBy('box', this.get('model')).length;
}.property('controllers.widgets.clickedWidgets.[]')
You can see a working bin here: http://jsbin.com/yizafe/1/edit
This should work for you, yes needs:['widgets'] is way to go: http://jsbin.com/tunuj/1/edit?html,js,output

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

Cannot read property 'container' of null when using linkTo helper in an Ember template

I am creating an Ember application as an add-on to some HTML returned from the server. I need this HTML so that the site can be indexed by search engines, and also to speed up the initial page rendering for the users.
So my application consists of several Ember Views, appended to different DOM elements of the HTML generated by the server. I don't use master templates for routes, so I set renderTemplate function of each route to do nothing.
My Ember App is bound to body element and I can successfully append a custom view to an element down the tree. It works:
In this JSFiddle three last elements of the list are appended by Ember
But when I try to use linkTo helper in my template, I hit an error:
Uncaught TypeError: Cannot read property 'container' of null ember-latest.js:32224
which is in this function:
router: Ember.computed(function() {
return get(this, 'controller').container.lookup('router:main');
}),
In this JS fiddle I just add linkTo to the template, and it breaks everything
In general, can Ember work this way - having many Views scattered
over the HTML rendered by the server?
How can the example code be
fixed?
I've fixed your fiddle here, Check it out.
Seems like you are starter to Ember,
So here are some tips for you,
You should have an application template, which will be the root template and on which all the templates will be rendered.
You shouldn't access views using this.container.lookup, that is for debugging only.
You shouldn't append views to the DOM, it's the job of the framework to do.
By default your application will be appended to the body of the html, if you want it to be appended elsewhere, give the rootElement property when creating the application. Refer here for configuring your application.
The rootElement can be either a DOM element or a jQuery-compatible selector string. Note that views appended to the DOM outside the root element will not receive events. If you specify a custom root element, make sure you only append views inside it!
Don't access any controllers globally like App.itemsController.set("content", model), if you want to access another controller inside a route, use this.controllerFor, and to access inside another controller, use needs.
You need not create any controller instance like App.itemsController=Ember.ArrayController.extend({}).create();
The framework will take care of all these.
I found that I need to additionally bind the view and the container together to make this fiddle work
App.itemsView.set("controller", App.itemsController);
App.itemsController.set("container", this.container);
So the resulting working code snippet is here:
http://jsfiddle.net/ddegtyarev/6cBRx/6/
Again, let me reiterate that I'm building an hybrid Ember application - i.e. I have some HTML returned right from the server, and some appended by multiple Ember views in multiple places. This is why I have to manually create the views and bind them with controllers etc.

Convenient way to inspect or introspect Ember Data source with DS.RESTAdapter

Is there a convenient way to inspect the raw model data being passed from external API to Ember js and Ember Data models?
Something like the Ruby .inspect method. Is there any debug tool like this in for Ember Data?
I want to make sure that I am properly mapping to the JSON when the data gets to my Ember models. But it would be handy to see the data structures before having to explicitly define the attributes in the model class on the Ember side.
I am wondering if there something roughly analogous to this pattern:
App.Somedata = DS.Model.extend({
raw: this.inspect
});
and then in my template I could just dump it to the view as a property that conveys the whole structure.
{{#each item in controller}}
{{item.raw}}
{{/each}}
This is not for production, but just for discovery purposes when trying to explore the implementation of an API and how it is served over the adapter.
There are two parts to debugging this, the first would be to inspect the JSON payload in your browser console. (In Chrome, check the Network tab).
To check the internal data being stored in an EmberData object there are actually two places that are used for internal housekeeping object.get('_data') and object.get('_reference').
In your case I think the data is what you are hoping for.
Your other options are to call object.toJSON() or object.serialize() to see what the representation that would be returned to the server in the current state.