Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dynamic subscriptions to re-frame #108

Closed
wants to merge 0 commits into from

Conversation

danielcompton
Copy link
Contributor

Dynamic subscriptions allow the user to create subscriptions that depend on Ratoms/Reactions and will be rerun when they change. Users will subscribe with v and a vector of dynamic values. The dynamic values are dereffed and passed to the handler-fn. Dynamic subscriptions need to pass a fn which takes app-db, v, and the dereffed dynamic values.

Every time a dynamic value changes, handler-fn will be rerun. This is in contrast to standard subscriptions where handler-fn will only be run once, although the reaction that it produces will change over time.

A concrete example of the need for this is:

  1. You want to subscribe to a query on a remote server which will return
    a Reaction which changes in response to server changes.
  2. You want this subscription to be able to be rerun when you change one
    of the query parameters.

In the current system, all views need to be aware of the possibility of changing parameters and provide them in their subscriptions.

Example usage code:

(register-sub
  :todo-dynamic
  (fn todo-dynamic [_ _ [active-list]]
    (let [q (q/get-query active-list)]
      q)))

(register-sub
  :todos
  (fn todos [db _]
    (let [active-list (subscribe [:active-list])
          todos       (subscribe [:todo-dynamic] [active-list])]
      (make-reaction (fn todo-vals [] (update @todos :result #(vals (:list %))))))))

Tasks:

  • Write docs showing usage

@danielcompton
Copy link
Contributor Author

I talked with @mike-thompson-day8 about this and he discovered a way to avoid calling run!. This is fixed in e01023a.

@mike-thompson-day8
Copy link
Contributor

Warn the programmer if any item in active-list does not implement reagent.ratom/IReactiveAtom (this covers ratoms, cursors and reactions).

We've had a case of someone accidentally passing in a string by mistake and it took them a while to find the reported problem (an exception about something getting derefed which shouldn't be)

@danielcompton
Copy link
Contributor Author

I've added an error message when passing non-reactive parameters. I'm open to better wording for the error though.

@mike-thompson-day8
Copy link
Contributor

@danielcompton my version of that error message and surrounds would be:

(when ^boolean goog.DEBUG
  (when-let [not-reactive-dynv (seq (remove (partial implements? reagent.ratom/IReactiveAtom) dynv))]
    (warn "re-frame: 3rd parameter to 'subscribe' should be a seq of input signals but you supplied non reactive items: " not-reactive-dynv)))

@danielcompton
Copy link
Contributor Author

I've used your code, and modified the error message slightly to give the technical details.

re-frame: 3rd parameter to 'subscribe' should be a seq of input signals (implementing IReactiveAtom) but you supplied non reactive items: 

While I think this is a pretty good solution and technically sound, I think we should mark this as experimental at first if we accept the PR.

@danielcompton
Copy link
Contributor Author

For anyone watching this issue, it's out in https://github.com/Day8/re-frame/releases/tag/v0.5.0-alpha1. Try it out in your apps and give us feedback.

@mike-thompson-day8
Copy link
Contributor

Released in version 0.5.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants