Angular2: convert array to Observable

92,671

Solution 1

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

Solution 2

import { of } from 'rxjs';
    
return of(this.contacts);

Solution 3

Some people like me want it differently, which is from string[] into Observable<string>.

This is an example which involves the 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);

Hopefully it will help some others.

Solution 4

In angular7 its enough to just put the of(). Whatever you put inside of() will be changed to observable. Here, this.contacts is converted to observable.

import { of } from 'rxjs';

getContacts() {
    if (this.contacts != null) {
        return of(this.contacts);
    }
}

Solution 5

Quick solution here:

getSomething(): Observable < Object[] > {
    return new Observable(observable => {
        this.http.get('example.com').subscribe(results => {
            observable.next(results.json());
            observable.complete();
        });
    });
}
Share:
92,671
Mathius17
Author by

Mathius17

Updated on June 20, 2020

Comments

  • Mathius17
    Mathius17 almost 4 years

    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');
      }
    }
    
  • Evan Plaice
    Evan Plaice about 8 years
    This is probably a dumb question but couldn't you just cache the observable itself and call .next() rather than caching the state and recreating the observable on each call?
  • Mathius17
    Mathius17 about 8 years
    Good point, I'll try it. Though it my not be the best for when I want to iterate the array to return a single contact by a specific key
  • Sal
    Sal almost 7 years
    import 'rxjs/add/observable/of';
  • David Sagang
    David Sagang over 5 years
    @Eric Martinez, thanks for your answer. Where do you get the of from. I imported that from 'rxjs' however it is not in the Observable.