How to return value from function which has Observable subscription inside?

Solution 1:

EDIT: updated code in order to reflect changes made to the way pipes work in more recent versions of RXJS. All operators (take in my example) are now wrapped into the pipe() operator.

I realize that this Question was quite a while ago and you surely have a proper solution by now, but for anyone looking for this I would suggest solving it with a Promise to keep the async pattern.

A more verbose version would be creating a new Promise:

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store.pipe(
           take(1) //useful if you need the data once and don't want to manually cancel the subscription again
         )
         .subscribe(
            (data:any) => {
                console.log(data);
                resolve(data);
         })
    })
}

On the receiving end you will then have "wait" for the promise to resolve with something like this:

getValueFromObservable()
   .then((data:any)=>{
   //... continue with anything depending on "data" after the Promise has resolved
})

A slimmer solution would be using RxJS' .toPromise() instead:

function getValueFromObservable() {
    return this.store.pipe(take(1))
       .toPromise()   
}

The receiving side stays the same as above of course.

Solution 2:

This is not exactly correct idea of using Observable

In the component you have to declare class member which will hold an object (something you are going to use in your component)

export class MyComponent {
  name: string = "";
}

Then a Service will be returning you an Observable:

getValueFromObservable():Observable<string> {
    return this.store.map(res => res.json());
}

Component should prepare itself to be able to retrieve a value from it:

OnInit(){
  this.yourServiceName.getValueFromObservable()
    .subscribe(res => this.name = res.name)
}

You have to assign a value from an Observable to a variable:

And your template will be consuming variable name:

<div> {{ name }} </div>

Another way of using Observable is through async pipe http://briantroncone.com/?p=623

Note: If it's not what you are asking, please update your question with more details

Solution 3:

If you want to pre-subscribe to the same Observable which will be returned, just use

.do():

function getValueFromObservable() {
    return this.store.do(
        (data:any) => {
            console.log("Line 1: " +data);
        }
    );
}

getValueFromObservable().subscribe(
        (data:any) => {
            console.log("Line 2: " +data)
        }
    );

Solution 4:

The problem is that data is captured inside the observable and I can just console log it. I want to return that value and console.log or whatever from different file by calling the function in which it resides.

Looks like you are looking for a "current value" getter inside an observable, when it emits and after an emission.

Subject and Observable doesn't have such a thing. When a value is emitted, it is passed to its subscribers and the Observable is done with it.

You may use BehaviorSubject which stores the last emitted value and emits it immediately to new subscribers.

It also has a getValue() method to get the current value;

Further Reading:

RxJS BehaviorSubject

How to get current value of RxJS Subject or Observable?

Solution 5:

While the previous answers may work in a fashion, I think that using BehaviorSubject is the correct way if you want to continue using observables.

Example:

    this.store.subscribe(
        (data:any) => {
            myService.myBehaviorSubject.next(data)
        }
    )

In the Service:

let myBehaviorSubject = new BehaviorSubjet(value);

In component.ts:

this.myService.myBehaviorSubject.subscribe(data => this.myData = data)

I hope this helps!