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');
  }
}
36
demandé sur Mathius17 2016-02-20 21:46:32

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);
    }
}
55
répondu Eric Martinez 2016-02-20 18:56:03

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.

3
répondu sancho21 2017-12-13 10:58:03

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.

0
répondu Daniel Morris 2017-04-14 22:57:16

solution Rapide ici:

getSomething():Observable<Object[]>{
        return new Observable(observable => {
            this.http.get('example.com').subscribe(results => {
                observable.next(results.json());
                observable.complete();
            });
        });
    }
0
répondu Mr.Zon 2017-11-29 21:15:46