J'ai un composant qui récupère les données d'un service via http, le problème est que je ne veux pas utiliser le backend de l'API à chaque fois que je montre ce composant. Je veux que mon service vérifie si les données sont en mémoire, si elles le sont, renvoient un observable avec le tableau en mémoire et, dans le cas contraire, effectuent 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');
}
}
Tu es juste là. Si vous avez déjà les données en mémoire, vous pouvez utiliser of
observable (é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, de string[]
à Observable<string>
.
Ceci 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);
J'espère que cela aidera d'autres.
import { of } from 'rxjs';
return of(this.contacts);
Cela risque d’être extrêmement tardif, mais j’utilise passablement sessionStorage pour gérer certains de mes travaux. Si vous perdez votre statut parce que les gens rebondissaient, 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 Subject 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'emplacement des données et il s'en fiche. Le service vérifie le stockage local et, s'il en a un, le convertit en observable et le renvoie. S'il ne le fait pas, il le récupère, puis l'enregistre dans un stockage local, puis le renvoie.
Dans mon cas, j'ai des applications énormes avec des centaines de pages. Les utilisateurs peuvent rebondir d'une nouvelle page Nice Angular4 vers un âge ASP classique, puis revenir plusieurs fois. Avoir tous les éléments de menu et même les résultats de recherche dans sessionstorage a été une bouée de sauvetage.
Solution rapide ici:
getSomething():Observable<Object[]>{
return new Observable(observable => {
this.http.get('example.com').subscribe(results => {
observable.next(results.json());
observable.complete();
});
});
}
Dans angular7, il suffit de mettre la of()
. Tout ce que vous mettez à l'intérieur. of()
sera changé en observable. Ici, this.contacts
est converti à observable.
import { of } from 'rxjs';
getContacts() {
if(this.contacts != null)
{
return of(this.contacts);
}
}