web-dev-qa-db-fra.com

Angular2: convertir un tableau en observable

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');
  }
}
42
Mathius17

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);
    }
}
62
Eric Martinez

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.

6
sancho21
import { of } from 'rxjs';


return of(this.contacts);
5
Mo D Genesis

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.

0
Daniel Morris

Solution rapide ici:

getSomething():Observable<Object[]>{
        return new Observable(observable => {
            this.http.get('example.com').subscribe(results => {
                observable.next(results.json());
                observable.complete();
            });
        });
    }
0
Mr.Zon

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);
    } 
}
0
kavinbalaji