Reputation: 2347
In ngOnInit()
I have "return x" which I want to put into Observable
, then perform transformations and return again in the same format.
Here is the working plunker: http://plnkr.co/edit/z26799bSy17mAL4P5MiD?p=preview
import {Component} from '@angular/core'
import { Observable } from 'rxjs'
import * as Rx from 'rxjs/Rx'
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<h2>{{name}}</h2>
<button (click)="addToArray()">Add</button>
<ul>
<li *ngFor="let item of data$ | async">{{ item }}</li>
</ul>
</div>
`,
directives: []
})
export class App {
data = ["one","two","three"]
data$: Observable<Array<string>>;
constructor() {
this.name = 'Angular2 array to observable example'
}
ngOnInit() {
this.data$ = Rx.Observable.of(this.data)
.map(data => {
let x = data
x.push("4")
///
/// TRANSFORM X IN THIS SECTION OF THE CODE
/// HERE BY PUTTING IT INTO OBSERVABLE
/// PERFORMING TRANSFORMATIONS AND
/// RETURNING THE DATA TO BE RENDERED IN TEMPLATE
///
return x
})
}
addToArray() {
this.data.push('more numbers')
}
}
Upvotes: 1
Views: 6540
Reputation: 123861
There is an adjusted and wirking plunker
I would implement that with an EventEmitter
and few operators, mostly
adjusted code
data = ["one","two","three"]
data$: Observable<string[]>;
protected emitter = new EventEmitter<string[]>();
constructor() {
this.name = 'Angular2 array to observable example'
this.data$ = this.emitter
.startWith(this.data)
.scan((orig, item) => orig.concat(item))
}
ngOnInit() {
// this.data$ = Rx.Observable.of(this.data)
// .map(data => {
// let x = data
// x.push("4")
// return x
// })
}
addToArray() {
//this.data.push('more numbers')
this.emitter.emit("forth")
}
Check it here
Much more complex plunker
There is much more complex solution.. just profiting from Observable and its Operators. It is ready to add and delete items:
data = ["one","two","three"]
data$: Observable<string[]>;
protected emitter = new EventEmitter<string[]>();
protected toDelete = new Rx.BehaviorSubject<string[]>([])
.scan((orig, item) => orig.concat(item));
constructor() {
this.name = 'Angular2 array to observable example'
this.data$ = this.emitter
// start
.startWith(this.data)
// return array
.scan((orig, item) => orig.concat(item))
// adjust each source string with a prefix
.map((coll: string[]) => {
let adjusted: string[] = []
coll.forEach(item => {
adjusted.push("x" + item)
})
return adjusted;
})
// now consume also array of items to be deleted
.combineLatest(this.toDelete)
// just those which were not delted
.map(([all, toDelete]:[string[], string[]]) =>{
let result = all.filter( function( el ) {
return toDelete.indexOf( el ) < 0;
});
return result;
})
}
counter: int = 0;
addToArray() {
this.emitter.emit(`other${++this.counter}`)
}
deleteFromArray(removeString) {
this.toDelete.next(removeString)
}
Check it in action here
There is a final plunker with lot of data: string\[\]
array handling
We can now even track the changes and let them adjust original data array, and even use the RESET function, to start from new begining. This is the adjusted code:
data = ["one","two","three"]
data$: Observable<string[]>;
protected emitter: EventEmitter<string[]>;
protected toDelete: Rx.BehaviorSubject<string[]>;
constructor() {
this.initEmitters();
this.data$ = this.createObservable(this.data);
}
initEmitters() {
this.emitter = new EventEmitter<string[]>();
this.toDelete = new Rx.BehaviorSubject<string[]>([])
.scan((orig, item) => orig.concat(item));
}
createObservable(initData)
{
let observable = this.emitter
// start
.startWith(initData)
// return array
.scan((orig, item) => orig.concat(item))
// adjust each source string with a prefix
.map((coll: string[]) => {
let adjusted: string[] = []
coll.forEach(item => {
adjusted.push("x" + item)
})
return adjusted;
})
// now consume also array of items to be deleted
.combineLatest(this.toDelete)
// just those which were not delted
.map(([all, toDelete]:[string[], string[]]) =>{
let result = all.filter( function( el ) {
return toDelete.indexOf( el ) < 0;
});
return result;
})
observable
.subscribe((currentData) => {
this.data.length = 0;
[].push.apply(this.data, currentData)
});
return observable;
}
counter: int = 0;
addToArray() {
this.emitter.emit(`other${++this.counter}`)
}
deleteFromArray(removeString) {
this.toDelete.next(removeString)
}
resetArray() {
this.initEmitters();
this.data$ = this.createObservable(['ten','eleven'])
}
Test that array
vs obesrvable
in action here
Upvotes: 1