@willgmbr
fb.me/wgrasel
The ReactiveX library for JavaScript.
[1, 2, 3]
.map(i => i * 2) // [2, 4, 6]
.filter(i => i > 5) // [6]
.concat([10, 20, 30]) // [6, 10, 20, 30]
Observable.of(1, 2, 3)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.of(10, 20, 30)
)
Observable.fromEvent(document, 'click')
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.fromEvent(document, 'blur')
)
Observable.from(function* (){ yield 9; })
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.from([10, 20, 30])
)
.subscribe(console.log)
Array.of(1, 2, 3)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Array.of(10, 20, 30)
)
Observable.interval(500)
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.of(10, 20, 30)
)
Observable.from(function* (){ yield 9; })
.map(i => i * 2)
.filter(i => i > 5)
.concat(
Observable.from([10, 20, 30])
)
<input type="text" [(ngModel)]="myInput">
<ul>
<li *ngFor="let r of results">{{r.name}}</li>
</ul>
<input type="text" [formControl]="myInput">
<ul>
<li *ngFor="let r of results">{{r.name}}</li>
</ul>
<input type="text" [formControl]="myInput">
<ul>
<li *ngFor="let r of results | async">{{r.name}}</li>
</ul>
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([]);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`);
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.mergeMap(url => this.http.get(url));
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.debounceTime(300)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.mergeMap(url => this.http.get(url))
.map(json => json['results']);
constructor(private http: HttpClient) {}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
myInput = new FormControl;
results = Observable.of([])
.merge(this.myInput.valueChanges)
.filter(v => v.length > 2)
.debounceTime(300)
.map(v => `https://swapi.co/api/people/?search=${v}`)
.switchMap(url => this.http.get(url))
.map(json => json['results'])
.retry(3);
constructor(private http: HttpClient) {}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().subscribe(user => {
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().pipe(
).subscribe(user => {
this.address = address;
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().subscribe(user => {
address.getAddressFromUser(user).subscribe(address => {
this.address = address;
})
})
}
}
@Component()
export class UserAddressComponent {
constructor (
user: UserService,
address: AddressService,
) {
user.getCurrentUser().pipe(
mergeMap(user => this.address.getAddressFrom(user))
).subscribe(address => {
this.address = address;
})
}
}
@Component()
export class MyComponent {
ngOnInit() {
interval(1000)
.subscribe(i => console.log(i));
}
}
@Component()
export class MyComponent {
unsubscribe = new Subject();
ngOnInit() {
interval(1000)
.subscribe(i => console.log(i));
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
@Component()
export class MyComponent {
unsubscribe = new Subject();
ngOnInit() {
interval(1000)
.pipe(takeUntil(this.unsubscribe))
.subscribe(i => console.log(i));
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
FOWLER, Martin. 2005
FOWLER, Martin. 2011
RxJS powered side effect model
Compose and cancel async actions to create side effects and more.