keechma

Keechma stack. Mention @U050986L9 or @U2J1PHYNM if you have any questions
roberto 2016-07-04T16:36:08.000138Z

is there a way to change the URL from within a controller?

roberto 2016-07-04T16:37:18.000139Z

I have a scenario where I have a component with lists of items, a component that displays a selected item, and a search component. When I type in the search bar, it fetches data form the server and modifies the list of items. But I want to add the search query to the url. Currently I’m sending an event from the search component to trigger the xhr call. But can’t find a way to update the URL.

mihaelkonjevic 2016-07-04T17:36:15.000140Z

@roberto you can use the redirect function in the controller https://keechma.com/api/keechma/keechma_controller/#var-redirect

roberto 2016-07-04T17:36:33.000142Z

yeah, I figured that out, now I’m stuck with something else

roberto 2016-07-04T17:36:42.000143Z

I redirect, and it gets parsed in the params function

roberto 2016-07-04T17:36:55.000144Z

but I can’t do a controller/execute from there

mihaelkonjevic 2016-07-04T17:38:37.000145Z

you have two options:

mihaelkonjevic 2016-07-04T17:38:54.000146Z

1. reset search controller on every change of search params and make a request

mihaelkonjevic 2016-07-04T17:39:37.000147Z

2. handle the :route-changed command in the handler function

mihaelkonjevic 2016-07-04T17:40:09.000148Z

:route-changed will be sent to every running controller every time something in the url is changed

mihaelkonjevic 2016-07-04T17:40:50.000149Z

so your params function could only check for the existence of the search params and then you can handle it manually in the handler function

mihaelkonjevic 2016-07-04T17:41:45.000150Z

route params that were present when the controller was started are readable from (:route-params controller)

roberto 2016-07-04T17:42:08.000152Z

ah, yeah, I think I found a way. I trigger a “redirect” within the function that gets called to do the search. I don’t need to worry about parsing the route in the params function to trigger another call.

roberto 2016-07-04T17:42:48.000153Z

I was doing something silly, took me a while to figure out how things work. I was triggering a do-search message, which redirected.

roberto 2016-07-04T17:43:10.000154Z

and then I was trying to trigger the real search message in the params function

roberto 2016-07-04T17:44:45.000155Z

I noticed one of my controllers gets started over and over tho, there is probably something wrong. Everytime my search params is triggered, the start function for one of my other controllers gets triggered.

mihaelkonjevic 2016-07-04T17:45:22.000156Z

how does the params function look for that controller?

roberto 2016-07-04T17:45:37.000157Z

(params [_ route]
    ;;Only run this controller when the route is home or "recordings".
    (prn "ROUTE IN RECORDINGS: " route)
    (let [route-data (:data route)]
      (if (or (and (= (:section route-data) "recordings")
                   (:page route-data))
              (= (:section route-data) "home"))
        {:section (:section route-data)
         :page    (:page route-data)
         :query    (:query route-data)}
        nil)))

mihaelkonjevic 2016-07-04T17:46:06.000158Z

you’re returning query inside the object so that’s probably why

mihaelkonjevic 2016-07-04T17:46:25.000159Z

it’s different every time the route changes

roberto 2016-07-04T17:46:50.000160Z

ok, so everytime the return value of params changes, the start function is called?

mihaelkonjevic 2016-07-04T17:46:54.000161Z

yes

roberto 2016-07-04T17:47:00.000162Z

I thought it was only called on initialization of the controller

mihaelkonjevic 2016-07-04T17:47:08.000163Z

yeah, it shuts down the old controller

mihaelkonjevic 2016-07-04T17:47:13.000164Z

and initializes the new one

mihaelkonjevic 2016-07-04T17:47:20.000165Z

it’s basically restarting the controller

mihaelkonjevic 2016-07-04T17:47:57.000166Z

stop will be called on the old controller instance first

roberto 2016-07-04T17:47:58.000167Z

ohhhh, ok. So , to sum it up, if params changes, we get a new controller.

mihaelkonjevic 2016-07-04T17:48:00.000168Z

yep

roberto 2016-07-04T17:48:17.000169Z

hmmm, ok, I see. Thanks, this is very helpful.

mihaelkonjevic 2016-07-04T17:49:07.000170Z

yeah, if you want to manually handle the query params (without controller restart) read the original value from (:route-params controller) and then listen to the :route-changed command inside the handler function

roberto 2016-07-04T17:49:26.000172Z

I think I can use (:route-params this) to get access to the query instead of returning it from params

mihaelkonjevic 2016-07-04T17:49:28.000173Z

although I would probably split it to a separate search controller

roberto 2016-07-04T17:49:32.000174Z

cool

roberto 2016-07-04T17:49:44.000175Z

yeah, I have a separate search controller

roberto 2016-07-04T17:50:01.000176Z

but the list controller has to re-fetch the list from the server based on the changes in the query

roberto 2016-07-04T17:50:22.000177Z

so I still want to inspect the routes, but I don’t want to be restarting the controller, right?

mihaelkonjevic 2016-07-04T17:50:27.000178Z

yes

roberto 2016-07-04T17:50:36.000179Z

cool

mihaelkonjevic 2016-07-04T17:51:09.000180Z

there are more patterns you can use… you could have the search controller sending the message to the list controller whenever it restarts

mihaelkonjevic 2016-07-04T17:51:44.000181Z

so you would do something like (send-command this [:list-controller-topic :query] query-data)

mihaelkonjevic 2016-07-04T17:51:51.000182Z

from the start function of the search controller

roberto 2016-07-04T17:52:31.000184Z

ok, but that would mean the search controller gets restarted with every change in the query, right?

mihaelkonjevic 2016-07-04T17:52:35.000185Z

yes

roberto 2016-07-04T17:52:49.000186Z

restarting the controller doesn’t re-render the component, right (unless the data changes)?

mihaelkonjevic 2016-07-04T17:53:33.000188Z

nope, and you can send the search command up to the search controller, debounce it there and redirect after let’s say 200ms

roberto 2016-07-04T17:54:06.000189Z

coo, that sounds much more cleaner. I was trying to debounce in the component itself.

roberto 2016-07-04T17:54:09.000190Z

which got nasty

mihaelkonjevic 2016-07-04T17:54:45.000191Z

yeah, that’s why controllers have the handler function, so you can use channels for that kind of logic

roberto 2016-07-04T18:21:34.000192Z

to send a command to another controller, how do I specify the name of the controller?

roberto 2016-07-04T18:21:44.000193Z

Do I need a handle on the instance of the controller?

roberto 2016-07-04T18:24:29.000196Z

nevermind, I see I can get access to it from the app-db

roberto 2016-07-04T18:35:55.000197Z

hmmm, any idea why this isn’t working?

(let [recordings-ctrl (get-in @app-db-atom [:internal :running-controllers :recordings])]
    (controller/is-running? recordings-ctrl)) ;; This is returning true  
    (controller/send-command recordings-ctrl :search-recording [args]))

roberto 2016-07-04T18:36:08.000198Z

I’m getting a Uncaught Error: nth not supported on this type cljs.core/Keyword error

mihaelkonjevic 2016-07-04T18:46:41.000199Z

so when you use send command

mihaelkonjevic 2016-07-04T18:46:50.000200Z

it always gets routed through the controller manager

mihaelkonjevic 2016-07-04T18:47:03.000201Z

so you need to specify both topic and command

mihaelkonjevic 2016-07-04T18:47:11.000202Z

so instead of :search-recording

mihaelkonjevic 2016-07-04T18:47:23.000203Z

it would be [:controller-topic :search-recording]

mihaelkonjevic 2016-07-04T18:47:54.000204Z

where are you sending the command from?

mihaelkonjevic 2016-07-04T18:48:01.000205Z

if you’re sending it from another controller

roberto 2016-07-04T18:48:02.000206Z

from another controller

mihaelkonjevic 2016-07-04T18:48:13.000207Z

you don’t need to get the controller instance

mihaelkonjevic 2016-07-04T18:48:17.000208Z

just send it on the correct topic

mihaelkonjevic 2016-07-04T18:48:33.000209Z

topic being whatever was the key in the controllers map when starting the app

mihaelkonjevic 2016-07-04T18:48:51.000211Z

so you wound send it like this:

mihaelkonjevic 2016-07-04T18:49:09.000212Z

(controller/send-command this [:controller-topic :command-name] args)

roberto 2016-07-04T18:49:44.000214Z

great

roberto 2016-07-04T18:49:45.000215Z

that works

roberto 2016-07-04T18:49:46.000216Z

thanks