How to disable the Ember query parameter router? - ember.js

I am looking to upgrade Ember for a legacy application that I am supporting. The problem is that Ember's query parameter router is causing application conflicts because the legacy application uses an existing custom query string parser that was written before Ember's implementation was added.
Is there a way to completely disable the Ember query string router so that it will ignore ? characters in the URL? In a different situation I would simply switch to Ember's query string router, however that is not possible due to the constraints on this release.
Thanks!
Here is some of the relevant code:
App.Router.map(function() {
this.resource('search', { path: '/search/:query'});
});
App.SearchRoute = Ember.Route.extend({
model: function(urlParams) {
var queryObj = utils.parseQueryString(urlParams.query);
App.mainSearcher.setQuery(queryObj.q);
}
});

Related

Fetch new data from API in jQuery plugin's callback

I am new to ember, so please treat me like a fool. What I'm trying to do first is to understand the concept.
In my application I heavily rely on few jQuery plugins they fetch new portion of data in their callbacks, that's how these plugins are designed, but I am not sure how can I trigger them to fetch a new portion of data from API passing to API updated query parameters after plugin has been rendered.
I have wrapped the plugin in a component, in component's template I send data to it as (I use emblem.js syntax here)
= plotly-chart chartData=model
In model I have
//app/models/data-points.js
import DS from 'ember-data';
export default DS.Model.extend({
// time: DS.attr(),
ch1: DS.attr(),
ch2: DS.attr(),
ch3: DS.attr(),
temperature: DS.attr(),
});
And then in component itself I fetch data
//app/components/plotly-chart.js
dataPoints: Ember.computed.map('chartData', function(item){
return item.getProperties('ch1', 'ch2', 'ch3', 'temperature');
}),
and make some manipulations with data, which isn't so important for the question itself.
Ah, and I have a route graph/ which later calls that component
//app/routes/graph.js
import Ember from 'ember';
export default Ember.Route.extend({
queryParams: {
start_timestamp: {
refreshModel: true
},
end_timestamp: {
refreshModel: true
}
},
model(params) {
return this.get('store').query('data-point', params);
}
});
So as you see I have tried to fetch new properties via query params, finally it works great if I just update the url in browser, but now can I trigger new call to API and fetch new data and get this new data in a component itself?
Also I'm struggling to understand what role controllers play in all of these. It is mentioned that controllers will be deprecated soon, but still used here https://guides.emberjs.com/v2.10.0/routing/query-params/
My code seems to work without controllers, so this is really confusing.
Also I suspect maybe I should use services for what I'm trying to achieve, but not sure how.
Ember experts, could you please point me into a right direction? The most important thing is how to fetch new portion of data from API with updated query parameters (query parameters to API itself, not nessesarely the ember application, but I suspect in ember-data it is the same thing? or not %) %) %)).
UPDATE 1
Really I should use services for that, shouldn't I? Pass arguments into a service and query a store there. Would that be a correct pattern?
Then query parameters in url are not the same as querying the store and is an independent thing. Am I right?
but how can I trigger new call to API and fetch new data and get this new data in a component itself?
If you change your queryParam values in a controller using an action (combined with your current route setup) it will adjust your route and re-call your API, as the values are bound together to make this particular use case simple :-) You're about 98% of the way there ... :-)
Re controllers going away, they won't for a long time as the replacement hasn't been worked out yet. You could do some of this in a service if you want to, but there is no need as you are almost done.
Thanks, that make sense though. I just worried I'm doing it wrong.
By they way finally I found a way to access store from the controller Access store from component but:
1. I was unable to take out the data from that variable, probably it's me being stupid.
2. I double it's the right way to access store directly in a component and better to use services for that or rely on “Data Down Actions Up” (DDAU) paradigm?
Finally I was able to fetch new portion of a data calling a controller's action from within the controller, but then the next problem raised - the data was updated, but the JS code did not know about that because I feed the jQuery plugin with this data and it did not pick up changes automatically. I think I might be doing it a wrong way there %)
But finally I get it working by adding an Ember's observer to that variable and in observer calling a redraw function (for chart in this particular place).
#acorncom Thanks!

subdirectories within ember controller not working

from this post it seems that sub directories within ember controller should work.
https://github.com/ember-cli/ember-cli/issues/1219
however its not working for me .
here is my code branch like (directory cm contains a child directory views):
/controllers/cm/views/item.js
/routes/cm/views/item.js
/templates/cm/views/item.js
when i try to populate the model in route using the code below i see the data but when i put the same code in controller it never gets executed.
model: function(){
return this.store.find('item',{id: "1"});
}
entry in router.js is as follows:
this.resource('cm', {path: '/cm/:id'} , function() {
this.route('views');
this.route('views.items', {path: '/views/items'});
});
Clearly ember is not able to resolve the controller correctly.
Not sure how to fix this ...
That its becuase the model hook in a route works differently than in the controller.
in a route it is a method that can return a promise, the route will wait for the promise to be resolved before setting up the controller.
in the controller, it is just an attribute, which won't get executed until you getit, and even then, all you will get its a promise.
Wat?! Subdirectories work just fine. First, I'm not sure it's the best idea to use views or items as route names, as they're both very generic, and also used in some of the ember internals and can confuse things. Declaring a model called View could very well even break things in your app.
The controller/route/template structures for your router.js will be as follows:
<controllers|routes|templates>/cm.js
<controllers|routes|templates>/cm/index.js
<controllers|routes|templates>/cm/views.js
And I'm not sure what views.items would look like, because this would probably be better suited to making views a resource instead, or using a dash in the name, in which case the route declaration would be this.route('views-items', {path: '/views/items'});
Overall, I think your router definition should look like so:
this.resource('cms', function() {
this.resource('cm', {path: '/:cm_id'}, function() {
this.route('views');
this.route('views-items', { path: '/views/items' });
});
});
This isn't meant to be a quip--I'm here to help--but I think you need to spend a little more time with Ember's routing documentation to understand the conventions that Ember is expecting for certain router definitions. Also, the ember inspector tool is a really great asset when debugging router issues: https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi

Ember Routing: Reusing a resource under multiple parent routes

I have the following routing setup:
this.resource('blog',function(){
this.resource('selectimage',{path:"selectimage/:returncontext"},function(){});
});
this.resource('post',{path:":post_id"},function(){
this.resource('selectimage',{path:"selectimage/:returncontext"},function(){});
});
What I would have expected is, when navigating to blog.selectimage and post.selectimage, that the same router,controller and view would be used.
Unfortunately it seems that the last entry wins.
Is it possible to achievie this, without leaving the parent context(post/blog), when navigating to selectimage
(Obviously I could inherit from the base-selectimages-classes, but I'm hoping there is some generic ember way of doing this.)
You cannot have same resource name for two different routes as Ember relies more on naming conventions. But Ember provides ways to reuse the same controller and templates
Rename your selectimage under post to something else
this.resource('post',{path:":post_id"},function(){
this.resource('xxx',{path:"xxx/:returncontext"});
});
And in the router, you could specify the templateName and controller that has to be reused. Something like this should make it reusable
App.xxxRoute = Em.Route.extend({
controllerName: 'selectimage',
templateName: 'selectimage'
});
Sample Demo

Ember Data's API call signature

I'm a newbie to Ember Data and I've just switched from FIXTURE data to the RESTAdapter but I don't know enough about how to connect the model and the API's call signature. Specifically I'd like to be able to call an endpoint GET /activities/[:user_id]/[:by_date]. This would load an array of "Activity" objects but only those for a given date.
Router:
this.resource('activities', { path: '/activities' }, function() {
this.route('by_date', {path: '/:user_id/:by_date'});
});
Route:
App.ActivitiesByDateRoute = Ember.Route.extend({
serialize: function(activity) {
return {
userId: 1,
dateBy: "2013-07-01"
};
}
});
First off I tried to hard code the values for userId and dateBy making the adjustments to the Route above. Sadly that did not work. I think I understand why -- although I don't have a quick way to fix this -- but more disturbing for me was that when I manually put in the parameters into the URL: http://restful.service.com/api/activities/1/2013-07-01. The results are quite surprising to me:
Initially the debugging messages suggest a success:
This however, is not correct as no network requests are actually made
If you reload the browser, it will now go out and get the Activities but to my surprise it also goes out to find the specified user. Hmmm. That's ok, the user 1 is pulled back successfully.
The Activity, however, is just a GET /activities call which fails because this endpoint needs the user and date qualifier to work. Why weren't these included in the request?
I don't think ember data supports "composite keys" (which is essentially what you are trying to do). You'd probably need to build your own Ajax for that specific model and implement it in the model hook for that specific route. You can always fetch the data and sideload it into ember-data if you'd like to have an ember data model.

replaceRoute not working as expected?

I recently wanted some routes in my emberjs app not to show up in the browser history and tried to leverage the replaceRoute functionality that was introduced in the RC1. Unfortunately it doesn't make any difference at all if I use transitionToRoute or replaceRoute.
Let's say I have 3 pages and I want page 1 to be skipped when going back in history.
App = Ember.Application.create({});
App.ApplicationRoute = Ember.Route.extend({
events: {goBack:function(){window.history.back();}}
});
App.Page1Controller = Ember.Controller.extend({
goToPage2: function(){
this.replaceRoute("page2")
}
});
App.Router.map(function() {
this.route("page1");
this.route("page2");
this.route("page3");
});
I've made a little JSFiddle example for testing http://jsfiddle.net/ripcurlx/Qmnrj/3/
Am I using the replaceRoute completely wrong, or is there a better solution to prevent certain routes not to be included in the browser history?
Thanks for any hints!
Unfortunately, this only works with location: "history". Browsers have no support for updating the hash without affecting history, whereas when using history states, there is the provided replaceState method which we can utilize.