Angular2: convert array to Observable
Solution 1
You're right there. If you already have the data in memory, you can use of
observable (equivalent of return/just
in RxJS 4).
getContacts() {
if(this.contacts != null)
{
return Observable.of(this.contacts);
}
else
{
return this.http.get(url)
.map(res => <Contact[]> res.json())
.do(contacts => this.contacts = contacts)
.catch(this.handleError);
}
}
Solution 2
import { of } from 'rxjs';
return of(this.contacts);
Solution 3
Some people like me want it differently, which is from string[]
into Observable<string>
.
This is an example which involves the conversion:
import { from } from 'rxjs/observable/from';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toArray';
const ids = ['x12', 'y81'];
let userUrls: string[];
from(ids) // Converting string[] into Observable<string>
.map(id => 'http://localhost:8080/users/' + id)
.toArray()
.subscribe(urls => userUrls = urls);
Hopefully it will help some others.
Solution 4
In angular7 its enough to just put the of()
. Whatever you put inside
of()
will be changed to observable. Here, this.contacts
is converted
to observable.
import { of } from 'rxjs';
getContacts() {
if (this.contacts != null) {
return of(this.contacts);
}
}
Solution 5
Quick solution here:
getSomething(): Observable < Object[] > {
return new Observable(observable => {
this.http.get('example.com').subscribe(results => {
observable.next(results.json());
observable.complete();
});
});
}
Mathius17
Updated on June 20, 2020Comments
-
Mathius17 almost 4 years
I have a component that gets the data from a service via http, the problem is that I don't want to hit the API backend every time I show this component. I want my service to check if the data is in memory, if it is, return an observable with the array in memory, and if not, make the http request.
My component
import {Component, OnInit } from 'angular2/core'; import {Router} from 'angular2/router'; import {Contact} from './contact'; import {ContactService} from './contact.service'; @Component({ selector: 'contacts', templateUrl: 'app/contacts/contacts.component.html' }) export class ContactsComponent implements OnInit { contacts: Contact[]; errorMessage: string; constructor( private router: Router, private contactService: ContactService) { } ngOnInit() { this.getContacts(); } getContacts() { this.contactService.getContacts() .subscribe( contacts => this.contacts = contacts, error => this.errorMessage = <any>error ); } }
My service
import {Injectable} from 'angular2/core'; import {Http, Response, Headers, RequestOptions} from 'angular2/http'; import {Contact} from './contact'; import {Observable} from 'rxjs/Observable'; @Injectable() export class ContactService { private contacts: Array<Contact> = null; constructor (private http: Http) { } getContacts() { // Check first if contacts == null // if not, return Observable(this.contacts)? <-- How to? return this.http.get(url) .map(res => <Contact[]> res.json()) .do(contacts => { this.contacts = contacts; console.log(contacts); }) // eyeball results in the console .catch(this.handleError); } private handleError (error: Response) { // in a real world app, we may send the server to some remote logging infrastructure // instead of just logging it to the console console.error(error); return Observable.throw(error.json().error || 'Server error'); } }
-
Evan Plaice about 8 yearsThis is probably a dumb question but couldn't you just cache the observable itself and call .next() rather than caching the state and recreating the observable on each call?
-
Mathius17 about 8 yearsGood point, I'll try it. Though it my not be the best for when I want to iterate the array to return a single contact by a specific key
-
Sal almost 7 yearsimport 'rxjs/add/observable/of';
-
David Sagang over 5 years@Eric Martinez, thanks for your answer. Where do you get the of from. I imported that from 'rxjs' however it is not in the Observable.