Angular2: convert array to Observable

Mathius17 picture Mathius17 · Feb 20, 2016 · Viewed 73.5k times · Source

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

Answer

Eric Martinez picture Eric Martinez · Feb 20, 2016

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