Skip to content

Commit

Permalink
feat: allow a callback to the subscribe decorator
Browse files Browse the repository at this point in the history
Provides an easier means to create and bind a property to an Observable
  • Loading branch information
alexlafroscia committed Feb 7, 2019
1 parent 05582f3 commit 7ab8394
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 112 deletions.
35 changes: 29 additions & 6 deletions addon/decorators/subscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,25 @@ import { assert } from "@ember/debug";
* If the dependent observable is replaced, the original subscription will
* be unsubscribed from and the new observable subscribed to automatically.
*
* Additionally, you can provide a function to the decorator that returns an
* Observable. In that case, the returned Observable will be the one that values
* are received from.
*
* ```javascript
* export default class ShowLastTransition extends Component {
* @service router;
*
* @subscribe(i => fromEvent(this.router, 'routeWillChange'))
* lastTransition
* }
* ```
*
* @param {string} observableKey
*/
export default function subscribe(observableKey) {
assert(
"Must be passed a property to listen to",
typeof observableKey === "string"
"Must be passed a property to listen to or function to create an observable from",
typeof observableKey === "string" || typeof observableKey === "function"
);

const SUBSCRIPTION = Symbol();
Expand Down Expand Up @@ -91,21 +104,31 @@ export default function subscribe(observableKey) {
set(this, rest.key, value);
});
}

return class extends klass {
init() {
super.init(...arguments);

this.addObserver(observableKey, this, resetSubscription);
let observable;

if (typeof observableKey === "string") {
this.addObserver(observableKey, this, resetSubscription);

observable = get(this, observableKey);
}

if (typeof observableKey === "function") {
observable = observableKey.apply(this, [this]);
}

const observable = get(this, observableKey);
this[SUBSCRIPTION] = observable.subscribe(value => {
set(this, rest.key, value);
});
}

willDestroy() {
this.removeObserver(observableKey, this, resetSubscription);
if (typeof observableKey === "string") {
this.removeObserver(observableKey, this, resetSubscription);
}

if (this[SUBSCRIPTION]) {
this[SUBSCRIPTION].unsubscribe();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@ import { fromPropertyChange, subscribe } from "ember-rx";
import { scan } from "rxjs/operators";

export default class CountPropChanges extends Component {
value = "Initial Value";
value = "Replace this text";

@subscribe("value$") count = 0;

constructor() {
super(...arguments);

this.value$ = fromPropertyChange(this, "value").pipe(
scan(count => count + 1, 0)
);
}
@subscribe(i =>
fromPropertyChange(i, "value").pipe(scan(count => count + 1, 0))
)
count = 0;
}
// END-SNIPPET
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{{! BEGIN-SNIPPET count-prop-changes-example.hbs }}
<input
value={{value}}
placeholder="Type some stuff"
oninput={{action (mut value) value='target.value'}}
/>

Expand Down
Loading

0 comments on commit 7ab8394

Please sign in to comment.