Using ember.object to manage QPs - is this a reasonable approach?


#1

Strap yourself in for a mega-newb post!!

Still learning ember. I like it, but I’ll admit, I’m struggling. v0.1 of my search-filtering app was spaghetti so I’m trying again from scratch

My search app manages state with query string parameters. Every time the QPs change, the model needs to refresh. The “easy” part is that I am using the same QPs on the front end as what is expected on the back end by my api. So i literally just pass them straight thru and it works.

My spaghetti code app had the URL as the source of truth for state. But now I’m thinking of using an Ember.Object that contains the QPs as properties. This way I can have my actions operate on something “native” to ember and not try to roll my own QP manager. Also, I can set an observer on the object, and when it changes, update the properties and do a transitionTo with the new params (I think?). Plus, the data in the object affects the view, so any changes in it will automatically update there.

Would this be the “ember” way, or am I off-base?

If it’s the right approach, is this roughly how it would look? I imagine it would go in the route.

const UrlObj = Ember.Object.extend({
	queryParams: {
		q: null,
		filter_breadcrumb: null,
		filter_price: null,
		filter_size: null,
		search_page: 1,
		paging: 18,
		search_sort: 'relevance'
	},
	
	watchObj: Ember.observer(
		'queryParams.q',
		'queryParams.filter_breadcrumb',
		'queryParams.filter_price',
		'queryParams.filter_size',
		'queryParams.search_page',
		'queryParams.paging',
		'queryParams.search_sort',	
	function() {
		// serialize object for use on URL
		let newUrl = '/search?' + Ember.$.param(this.get('queryParams');
		// specifying QPs each time overrides stickyness
		this.transitionTo(newUrl);
	}),

});
let urlData = UrlObj.create();

Then there would be route actions that handle the actual updating of the ember object:

...
	actions: {
		addOrUpdateParam: function(key, value) {
			urlData.queryParams.set(key, value); 
		},
		removeParam: function(key) {
			urlData.queryParams.set(key, null);
		}
	}
...

That’s basically pseudo-code, I am pretty sure code like that won’t work. But I’m just looking for guidance on whether this is the “ember way” to approach it.


#2

Have you had a chance to check out the query params api?

https://guides.emberjs.com/v2.11.0/routing/query-params/

Let me know if that helps.


#3

Thanks. Yes, I was trying that out, but the problem I was having was with the sticky params. But now that I look again, I think I was just implementing wrong. OK, this gives me something to go on - thanks!


#4

OK, I think why I initially moved away from this is because controllers are going to be deprecated. I thought it would be good to keep the logic at the route level and the presentation at the component level. But being a beginner I think I should not try to get fancy.

But I am actually running into the same problem with sticky params. The docs state (after showing an example):

once the articles route has been entered, any changes to the category query param in the URL will update the category property on controller:articles, and vice versa

I take “vice versa” to mean that if there’s a change to one of the controller properties, it would also be reflected in the QPs on the URL. perhaps I am mis-interpreting that. But if my interpretation is correct, it’s not what’s actually happening.

I put together a twiddle to demonstrate

Is there a way to bind the QPs on the url to the controller properties so that

a) the controller properties update if the url QPs update b) the QPs in the location bar update if the controller properties update ?


#5

https://ember-twiddle.com/9d9b14e8e07dc56b973f65bba25d2a18

I added a few buttons to show that you can just update the properties to update query param.

In your twiddle you are trying to link to ?foo[]=1. I don’t believe that works in ember. So, I shoved a comma separated URL param example in the twiddle so you can use something like ?pretty=1,2,3


#6

Interesting! Thanks man. Yeah I found a thread on twitter about it and I guess maybe JSON is now being used for query param arrays.
Thanks for your help.


#7

This is not something you should be worrying about as you build ember apps today. Controllers are not deprecated and you should continue to use them as normal. If and when things change, there will be an upgrade path provided.


#8

definitely agree here. @midget2000x when I first was learning Ember, I had thought controllers were going to die. This post, locks quite helpfully explains some of the backdrop and future of controllers. https://locks.svbtle.com/controllers-are-dead-long-life-controllers