Passing parameters between routes in Ember 2.x - ember.js

While going from one route to another, I want to pass some data (especcially arrays). How is it possible?
Why can't we use query-params with arrays?
Is it a problem storing data in a specific service during transition?
Note:
I know there are some old questions those are nearly the same with this question. But their selected answers are no more applicable for Ember 2.x. Those questions are: 1, 2.

I´m not sure if queryparams won´t work with arrays as I only used it with single ids, but it would not be a good solutions even if it worked, there´s a limit on how much you can send by parameters and you should not bother any user with your data.
Just create a model to save your data for local use, so you can simply use the ember store
Use a service you´ll have to inject in every controller you want to use your data
I would prefer the model/store variant so you´ll be able to observe and just follow the normal flow which is also good if someone else has to maintain your code.

UPDATED
After testing with "transition.data"; not updating the history seems as a problem for us. So we again use "queryParams". The constraint is: do not pass a complex object between routes
OLD ANSWER
I'm using transition object for this purpose in an action while routing as the following:
let transition = router.transitionTo(route, model);
transition.data[propName] = propValue;
Also I wrote a component to use this code as link-to.

Related

Ember Data: Pushing the data to the store will not replace the changedAttributes of the record?

I am using Ember Data and I have a model say my-model. I am having a realtime notification server to update my application if there is any change for a record. When I am editing an attribute of my-model from UI, the model has some changedAttributes and when the real time notification comes, I am fetching the record from the server and pushing it to the store using store.push(store.normalize('my-model', data)).
Now, In the store the model still has my changedAttributes and it is not replaced. So I believe, the Ember Store will not replace the entire record and will replace only the clean attributes of the record when I do a store.push. I just want to confirm the behaviour. Can someone confirm if my understanding about this is right?
For something like this I think your best bet is to add a test to ember data itself to cover the desired behavior. This would be much more reliable than anything you might hear on Stackoverflow.
I've written a small Ember Twiddle to test that behavior: https://ember-twiddle.com/a8eb87a1c7e5019214320d81af05aca5?openFiles=templates.application.hbs%2C As it shows ember-data does not reset dirty attributes if the record is pushed again into the store - at least not for the tested version 3.4.2, which is a little bit outdated.
I wasn't able to find any tests in ember-data repository that covers your use case but I'm also not that familiar with Ember Data's source code. So you might want to open an issue there or ask on Ember Community Discord or Ember Discussion Forum if this is expected behavior.
To be honest I guess there should be a straight-forward solution to your problem as realtime notification (e.g. through WebSocket) is a common use case.

When should I use controllers vs routes in EmberJS?

I know this question might seem a little duplicate but the other version of this question is old and some of the content (such as Views) aren't even a part of ember anymore.
I'm about 4 weeks into my internship as a front-end developer working with EmberJS. I still don't understand when it's better to use the route over the controller or vice-versa. It seems to me that every action in the route can also be used in the controller.
The one recent thing I heard was that ember routes should be stateless where as controllers should be stateful.
What is the current state of controllers and routes. When should one be used over the other?
Consider the following example to understand the state of a controller (or route, or anything), in simple terms and in current context -- lets say you have a page (like a form) with three tabs; each tab can be considered as a state - it would call different components based on the state (or the tab you are in). Now if you would happen to go back for some reason, and hit the form link again, you would see that the state would remain the same. (if you were on tab 2 when you hit back, on returning to the form, you would still be on tab 2).
So to maintain these states, controllers are the way to go, since they are singletons. Route would have lost that information, and started fresh. So basically your variables/objects in a controller would define the 'state'.
Route-actions can be as easily used as controller actions- see https://github.com/DockYard/ember-route-action-helper. So if your template for this route is just using model as the object directly, and you don't need to maintain the 'state', you can pretty much do without your controller.
But if your template was using variables which needed manipulation, you would need controller.
Hope this helps!

How to pass an object to link-to + queryParams in Ember?

I'm currently in a situation that I need to pass one object to {{link-to}}, but queryParams does not accept objects {key:value}. I need this feature because I'm using this component in different templates. The reason for doing that is that one template uses some keywords to use as a filter that the other template does not use and vice-versa.
I started using my own helper to generate the link, but I realize that the anchor my helper was generating was reloading the whole page and link-to does not do that. I'd like to reproduce that behavior, because there are other variables set on the view which I'm using and they all get reset to their default values whenever I reload the page
Is there a smart way to create a link using objects now? I saw some answers but they were all related to ember 1.+ and canary. In all of the answers they were saying it was not possible. I wonder if people have implemented this now or if a solution for this problem is being used currently and I could not find...
Thanks!
So I really could not find a way to do this. What I've done instead was creating {{actions}} inside my anchors and then I used transitionTo() to simulate the behavior of {{link-to}}.
A nice way of doing that can be seen here
Ember transitionToRoute cleanly in a component without sendAction

Where i should put data managers

What is good practice for put data persisters in one place. For now i put model.save() in every controller when i save this object. But i think it is not good resolve, because it can make code duplicates.
I found in ember we have services https://guides.emberjs.com/v2.8.0/applications/services/, but according documentation it is place for not use data store.
My question is what is best practice for not duplicate data persist code?
Have you tried extending some base controller or maybe extending controllers with a mixin containing the actions and the logic? I think mixins would be the way to go for that.

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