Multiple Highcharts based charts using ember.js - ember.js

My requirement is as follows:
I will be intially fetching my list of reports which will contain only the report Id.Based on the report Id, I need to fetch the data for each report .I have partially succeeded in achieving this requirement. Please find the link below:
http://jsbin.com/ditazibowe/1/edit
Now I need to somehow pass the reportId from my template to my model , so that it fetches the data for each report based on the id. Is this possible to achieve? Any pointers will be helpful.
Thanks in advance.

Modify the model a bit and replace all calls to jquery $ with this.$ in order to use the context of the specific context.
example,
http://jsbin.com/zawameqilo/1/edit?html,js,output
js
App.IndexRoute = Ember.Route.extend({
model:function()
{
var reportModel = [];
reportData.forEach(function(reportDataItem){
var reportDataObject = Ember.Object.create({});
reportDataObject.reopen({
reportId:reportDataItem.reportId,
chartOptions:{chart:{
type: 'line',
}},
graphData:function(){
return fetchData(this.get("reportId"));
}.property("reportId")
});
reportModel.pushObject(reportDataObject);
});
return reportModel;
}
});
....
this.$('.chart').highcharts(chart);
....
hbs
<script type="text/x-handlebars" data-template-name="index">
{{#each model}}
<h1>{{reportId}}</h1>
{{chart- chartOptions=chartOptions reportId=reportId series=graphData}}
{{/each}}
</script>

Related

Using Ember.js, how do I get a template to show dynamically all of the properties of a model? [duplicate]

Is there a way to iterate over a view's context's attributes in EmberJS? I am using Ember-Data (https://github.com/emberjs/data) for ORM.
Lets say I use connectOutlets to register a UserView with a user that has attributes such as email, name, etc. In the connected Handlebars template, is there anyway that I can iterate over those attributes?
I basically need to build a generic view that can be reused with different models...
Ryan is right about the attributes, but it takes some doing to actually get where you're going. My examples here are using the latest RC1 Ember.
Here is an editor template that is model agnostic:
<script type="text/x-handlebars" data-template-name="edit_monster">
{{#if clientId}}
<h1>Edit Monster: {{name}}</h1>
<div>
{{#each metadata}}
<span class="edit-label">{{name}}</span>
<span class="edit-field">
{{view App.AutoTextField typeBinding="type" nameBinding="name" }}
</span>
{{/each}}
</div>
{{else}}
No monster selected.
{{/if}}
</script>
To make that work, we need a couple of pieces of magic-magic. This controller is a good start:
App.EditMonsterController = Em.ObjectController.extend({
metadata: function() {
var vals = [];
var attributeMap = this.get('content.constructor.attributes');
attributeMap.forEach(function(name, value) {
vals.push(value);
});
return vals;
}.property('content')
});
That uses that "attributes" property that Ryan mentioned to provide the metadata that we are feeding into our #each up there in the template!
Now, here is a view that we can use to provide the text input. There's an outer container view that is needed to feed the valueBinding in to the actual textfield.
App.AutoTextField = Ember.ContainerView.extend({
type: null,
name: null,
init: function() {
this._super();
this.createChildView();
},
createChildView: function() {
this.set('currentView', Ember.TextField.create({
valueBinding: 'controller.' + this.get('name'),
type: this.get('type')
}));
}.observes('name', 'type')
});
Here is a fiddle demonstrating the whole crazy thing: http://jsfiddle.net/Malkyne/m4bu6/
The Ember Data objects that represent your models have an attributes property that contains all of the attributes for the given model. This is what Ember Data's toJSON uses to convert your models into Javascript objects.
You can use this attributes property to read a models attributes and then pull those specific attributes out of an instance. Here is an example.
http://jsfiddle.net/BdUyU/1/
Just to reiterate what's going on here. We are reading the attributes from App.User and then pulling the values out of App.ryan and App.steve. Hope this makes sense.

Ember DjangoRESTAdapter data not loading

I'm pretty new to Ember so hopefully I'm just doing something stupid, but I've been running into a lot of random issues with data not displaying properly and I now see in the Ember Debugger that my data does not exist until I hit a specific model data endpoint. For instance, I have a template to display all products, here's the route:
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.find('product');
}
});
the controller:
App.ProductsController = Ember.ArrayController.extend({
itemController: 'product'
});
the template:
<script type="text/x-handlebars" data-template-name="products">
<div class="row">
{{#each}}
{{name}}
{{/each}}
</div>
</script>
Hitting the endpoint '/products' displays nothing initially, but if I go to '/products/1' I can see the product data in the view (and in the Ember debugger), and then if I navigate back to '/products' that particular product's data (but no other data) displays properly. So I'm super confused as to what I'm doing wrong. As the title suggests, I'm using the DjangoRESTAdapter if that helps narrow things down and here's my app.js as well
window.App = Ember.Application.create({});
window.api_location = 'http://localhost:8000/api';
App.ApplicationAdapter = DS.DjangoRESTAdapter.extend({
host: api_location,
pathForType: function(type) {
return Ember.String.underscore(type);
}
});
App.ApplicationSerializer = DS.DjangoRESTSerializer.extend({
});
App.Store = DS.Store.extend();
Thanks in advance for any help, and let me know if other code snippets would help.
Okay, I finally figured this out: it's an issue with pagination. I was not aware that we had pagination set up for our Django REST Api, so instead of returning a list of objects, it was returning a result object, with the list of products buried in a 'results' attribute. So until I can convince the other devs to turn off pagination I can modify all my queries:
this.store.find('product', {page_size:0});
to override our default page size.
Edit: I'm also trying out modifying the json response on the server side rather than using the djangorestadapter with this library: https://github.com/ngenworks/rest_framework_ember . Hopefully this saves some people some digging...

Ember route map url with query parameters

this is my route configuration (route.js using ember-cli)
this.resource('xero-invoices', {path:'/loans/xero/:loan_id/invoices'})
but ember cuts query string when trying to route this address . How to fix problem?
The portion of your route definition had a minor typo missing a closing curly brace, but I am assuming that is not really the issue. Here it is fixed for clarity.
this.resource('xero-invoices', {path:'/loans/xero/:loan_id/invoices'})
The resource above has a dynamic segment of lone_id not a query string. Query string support is currently in the beta builds of Ember and not in stable. Any query string functionality you are trying to use would be handled in your controller. http://emberjs.com/guides/routing/query-params/
If you had a jsbin or more code I may be more helpful.
Here is a trivial jsbin showing the dynamic segment working - http://emberjs.jsbin.com/casana/1/edit
Edit:
In your example jsbin you are trying to use the (query-parms) helper for link-to which is only available if you are using the beta version of Ember. In your application controller if you remove it from your application template you won't get an error. In your route, since you are returning the query param as the model, the oauth_token is accessible via the model property in the controller.
Source: http://jsbin.com/bufukiqisika/8/edit
App = Ember.Application.create();
App.Router.map(function() {
this.resource('xero-invoices', { path:'/loans/xero/:loan_id/invoices' });
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return ["red","blue","green"];
}
});
App.XeroInvoicesRoute = Ember.Route.extend({
model: function(params) {
window.console.log(params);
return params.queryParams["oauth_token"];
}
});
Templates:
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="xero-invoices">
{{model}}
</script>
Example: http://jsbin.com/bufukiqisika/8#/loans/xero/09870987/invoices?oauth_token=foo
You can use query-parameters which are defined on controllers.
Something like this should work:
MyController = Ember.Controller.extend({
queryParams: ['searchvalue'],
searchvalue : null
})
And in you Template:
{{input type="text" valueBinding=controller.searchvalue}}
So your search value will be represented in the URL, e.g. “…/myapp/seach?searchvalue=foo”
See http://emberjs.com/guides/routing/query-params/

Different result from App.Model.find() and App.Model.find({params})

I'm trying to create a todo-app (original, right?) and have a problem that ember doesn't display my newly created objects if use find({some parameters}) instead of find().
The problem seems to be that App.Model.find() returns a different result than, for example, App.Model.find({checked: false}).
I've created TasksRoute and defined the model data as App.Task.find().
When using App.Task.find() I can create a new task by typing:
var task = App.Task.createRecord({name: "taskName"});
task.get("store").commit();
The list is updated and the view displays the newly created task.
But if I instead use App.Model.find({}), or with any other hash, and then create a task nothing happens.
Here's the html:
<script type="text/x-handlebars" data-template-name="application">
{{#linkTo "tasks"}}Tasks{{/linkTo}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="tasks">
{{#each controller}}
{{name}}<br />
{{/each}}
</script>
Javascript:
App = Em.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter: DS.RESTAdapter.create({url: "http://localhost/backend/"})
});
App.Task = DS.Model.extend({
name: DS.attr('string')
})
App.TasksRoute = Ember.Route.extend({
model: function() {
return App.Task.find();
}
});
App.Router.map(function(){
this.route('tasks');
});
App.TasksController = Em.ArrayController.extend({});
The reason that I don't want to use find() is that I want to be able to specify my query. For example I would like to be able to retrieve all tasks that are checked by providing a hash to find().
(I tried creating a jsFiddle but didn't manage to get it to work with fixtures)
Is this a bug or have I done something wrong?
Thanks in advance
You might want to use filterProperty('checked', false) instead of find({params})

Iterating over a model's attributes in EmberJS handlebars template

Is there a way to iterate over a view's context's attributes in EmberJS? I am using Ember-Data (https://github.com/emberjs/data) for ORM.
Lets say I use connectOutlets to register a UserView with a user that has attributes such as email, name, etc. In the connected Handlebars template, is there anyway that I can iterate over those attributes?
I basically need to build a generic view that can be reused with different models...
Ryan is right about the attributes, but it takes some doing to actually get where you're going. My examples here are using the latest RC1 Ember.
Here is an editor template that is model agnostic:
<script type="text/x-handlebars" data-template-name="edit_monster">
{{#if clientId}}
<h1>Edit Monster: {{name}}</h1>
<div>
{{#each metadata}}
<span class="edit-label">{{name}}</span>
<span class="edit-field">
{{view App.AutoTextField typeBinding="type" nameBinding="name" }}
</span>
{{/each}}
</div>
{{else}}
No monster selected.
{{/if}}
</script>
To make that work, we need a couple of pieces of magic-magic. This controller is a good start:
App.EditMonsterController = Em.ObjectController.extend({
metadata: function() {
var vals = [];
var attributeMap = this.get('content.constructor.attributes');
attributeMap.forEach(function(name, value) {
vals.push(value);
});
return vals;
}.property('content')
});
That uses that "attributes" property that Ryan mentioned to provide the metadata that we are feeding into our #each up there in the template!
Now, here is a view that we can use to provide the text input. There's an outer container view that is needed to feed the valueBinding in to the actual textfield.
App.AutoTextField = Ember.ContainerView.extend({
type: null,
name: null,
init: function() {
this._super();
this.createChildView();
},
createChildView: function() {
this.set('currentView', Ember.TextField.create({
valueBinding: 'controller.' + this.get('name'),
type: this.get('type')
}));
}.observes('name', 'type')
});
Here is a fiddle demonstrating the whole crazy thing: http://jsfiddle.net/Malkyne/m4bu6/
The Ember Data objects that represent your models have an attributes property that contains all of the attributes for the given model. This is what Ember Data's toJSON uses to convert your models into Javascript objects.
You can use this attributes property to read a models attributes and then pull those specific attributes out of an instance. Here is an example.
http://jsfiddle.net/BdUyU/1/
Just to reiterate what's going on here. We are reading the attributes from App.User and then pulling the values out of App.ryan and App.steve. Hope this makes sense.