Angular2: convertir le tableau en Observable
j'ai un component qui reçoit les données d'un service via http, le problème est que je ne veux pas frapper l'API backend chaque fois que je montre ce component. Je veux que mon service vérifie si les données sont en mémoire, si c'est le cas, renvoie un observable avec le tableau en mémoire, et si ce n'est pas le cas, effectue la requête http.
Mon composant
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
);
}
}
mon 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');
}
}
4 réponses
Vous êtes là. Si vous avez déjà les données en mémoire, vous pouvez utiliser of
observables (l'équivalent de return/just
dans 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);
}
}
certaines personnes comme moi le veulent différemment, ce qui est de string[]
en Observable<string>
.
C'est un exemple qui implique la 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);
espérons que cela en aidera d'autres.
cela pourrait être extrêmement tard pour venir, mais j'ai utilisé sessionStorage assez lourdement pour gérer une partie de mon travail. Si vous perdez l'état parce que les gens sautaient, vous avez toujours vos données.
getSubjects(): Observable<Subject[]> {
let SubjectsString = sessionStorage.getItem("Subjects")
if (SubjectsString) {
let subjects: Subject[] = JSON.parse(SubjectsString);
console.log("GETTING DATA FROM SESSION STORAGE")
return Observable.of(subjects);
} else {
let url = `${this.apiHost}/api/subject`;
return this.http.get(url)
.map(res =>{
sessionStorage.setItem("Subjects",JSON.stringify(res.json()));
return res.json();
})
}
}
dans cet exemple, j'ai une classe pour le sujet et une définition pour apiHost, mais le reste est assez simple. Vous appelez le service pour un observable. Votre composant n'a aucune idée de l'endroit où se trouvent les données et il s'en fiche. Le service vérifie local de stockage et, si elle l'a, le convertit en un observables et la retourne, si ce n'est pas, il va et il obtient, puis l'enregistre dans un stockage local et le renvoie.
dans mon cas, j'ai d'énormes applications avec des centaines de pages. Les utilisateurs pourraient rebondir d'une nouvelle page Angular4 nice, plus à un ASP age classique et de nouveau à plusieurs reprises. Avoir tous les éléments de menu et même les résultats de recherche dans sessionstorage a été un Sauveur.
solution Rapide ici:
getSomething():Observable<Object[]>{
return new Observable(observable => {
this.http.get('example.com').subscribe(results => {
observable.next(results.json());
observable.complete();
});
});
}