189
votes

Is the only difference between Observable.of and Observable.from the arguments format? Like the Function.prototype.call and Function.prototype.apply?

Observable.of(1,2,3).subscribe(() => {})
Observable.from([1,2,3]).subscribe(() => {})
8

8 Answers

136
votes

Not quite. When passing an array to Observable.from, the only difference between it and Observable.of is the way the arguments are passed.

However, Observable.from will accept an argument that is

a subscribable object, a Promise, an Observable-like, an Array, an iterable or an array-like object to be converted

There is no similar behaviour for Observable.of - which always accepts only values and performs no conversion.

232
votes

It is important to note the difference between of and from when passing an array-like structure (including strings):

Observable.of([1, 2, 3]).subscribe(x => console.log(x));

would print the whole array at once.

On the other hand,

Observable.from([1, 2, 3]).subscribe(x => console.log(x));

prints the elements 1 by 1.

For strings the behaviour is the same, but at character level.

21
votes

Another interesting fact is Observable.of([]) will be an empty array when you subscribe to it. Where as when you subscribe to Observable.from([]) you wont get any value.

This is important when you do a consecutive operation with switchmap.

Ex: In the below example, I am saving a job and then sites, and then comments as a stream.

.do((data) => {
            this.jobService.save$.next(this.job.id);
        })
        .switchMap(() => this.jobService.addSites(this.job.id, this.sites)
            .flatMap((data) => {
                if (data.length > 0) {
                    // get observables for saving
                    return Observable.forkJoin(jobSiteObservables);
                } else {
                    **return Observable.of([]);**
                }
            })).do((result) => {
            // ..
        })
        .switchMap(() => this.saveComments())
....

if there's no site to save, ie; data.length = 0 in addSite section, the above code is returning Observable.of([]) and then goes to save comments. But if you replace it with Observable.from([]), the succeeding methods will not get called.

rxfiddle

20
votes

One line Difference :

       let fruits = ['orange','apple','banana']

from : Emit the items one by one of array. For example

    from(fruits).subscribe(console.log) // 'orange','apple','banana'

of : Emit the whole array at once. For example

 of(fruits).subscribe(console.log) //  ['orange','apple','banana']

NOTE: of operator can behave as from operator with spread operator

 of(...fruits).subscribe(console.log) //  'orange','apple','banana'
8
votes

from: Create observable from array, promise or iterable. Takes only one value. For arrays, iterables and strings, all contained values will be emitted as a sequence

const values = [1, 2, 3];
from(values); // 1 ... 2 ... 3

of: Create observable with variable amounts of values, emit values in sequence, but arrays as single value

const values = [1, 2, 3];
of(values, 'hi', 4, 5); // [1, 2, 3] ... 'hi' ... 4 ... 5
4
votes
  1. from returns notification in chunks i.e. one by one. for eg: from("abcde") will return a => b => c => d => e
  2. of returns complete notification. for eg: of("abcde") will return abcde.

https://stackblitz.com/edit/typescript-sckwsw?file=index.ts&devtoolsheight=100

2
votes

The from operator takes source of events. from(source)

let array = [1,2,3,4,5]
from(array); //where array is source of events, array[of events]


let promise = new Promise(function(resolve, reject) {
  // executor (the producing code, "singer")
});
from(promise); //where promise is source of event, promise(of event)





let observable = Observable.create(function(observer) {
  observer.next(1);
  observer.next(2);
  observer.next(3);
  observer.next(4);
  observer.next(5);
  observer.complete();
});
from(observable); // where obsservable is source of events. 

The of operator takes intividual events. of(event1, event2, event3)

of(1,2,3,4,5); // where 1,2,3,4,5 are individual events
0
votes

from operator may accept one of

promises iterable arrays observable

from emits each individual item from the observable , can also do conversions.

of operator takes in the raw value and emits the value from the observable.

import {from, Observable, of} from 'rxjs';

const ofObs = of([1,2,3]);
const fromObs = from([2,3,4]);

const basicObs = Observable.create(observer=>{
    observer.next(100);
    observer.next(200);
    observer.next(300);
})
const promise = new Promise((resolve,reject)=>{
    resolve(100);
})

const array = [1,2,3];
const iterbale  = "Dhana";

// const myObs = from(ofObs);//possible and can emit individual item value everytime 1, then ,2 , then 3
// const myObs = from(fromObs);//possbile and can emit individual item value everytime 1, then ,2 , then 3
// const myObs = from(basicObs);//possbile and can emit individual item value everytime 100, then ,200 , then 300
const myObs = from(promise);//possible can emit value 100
// const myObs = array(promise);//possible and can emit individual item value everytime 1, then ,2 , then 3
// const myObs = iterable(promise);//possible and can emit individual item value everytime D then h then a then n then a


myObs.subscribe(d=>console.log(d))



import {from, of} from 'rxjs';

const basicOf1 = of([1,2,3,4,5,6]) // emits entire array of events
const basicfrom1 = from([1,2,3,4,5,6]) //emits each event at a time

const basicOf2 = of(1,2,3,4,5,6) // emits each event at a time
// const basicfrom2 = from(1,2,3,4,5,6) //throws error
//Uncaught TypeError: number is not observable

const basicOf3 = of(...[1,2,3,4,5,6]) // emits each event at a time
const basicfrom3 = from(...[1,2,3,4,5,6]) //throws error
//Uncaught TypeError: number is not observable
basicOf3.subscribe(d=>console.log(d))

Here is the link to codepen