可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I dont know how to extract value from Observable to be returned by function in which Observable is present. I need just a value from it to be returned, nothing else.
Current version which works
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
console.log(data)
}
)
}
getValueFromObservable()
I need this to work, function to return value, and then:
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
return data
}
)
}
console.log(getValueFromObservable())
What am I doing wrong here?
回答1:
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
.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
.take(1)
.toPromise()
}
The receiving side stays the same as above of course. Hope that helps!
回答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
回答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)
}
);
回答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?
回答5:
Observable values can be retrieved from any locations. The source sequence is first pushed onto a special observer that is able to emit elsewhere. This is achieved with the Subject class from the Reactive Extensions (RxJS).
var subject = new Rx.AsyncSubject(); // store-last-value method
Store value onto the observer.
subject.next(value); // store value
subject.complete(); // publish only when sequence is completed
To retrieve the value from elsewhere, subscribe to the observer like so:
subject.subscribe({
next: (response) => {
//do stuff. The property name "response" references the value
}
});
Subjects are both Observables and Observers. There are other Subject types such as BehaviourSubject and ReplaySubject for other usage scenarios.
Don't forget to import RxJS.
var Rx = require('rxjs');
回答6:
For example this is my html template:
<select class="custom-select d-block w-100" id="genre" name="genre"
[(ngModel)]="film.genre"
#genreInput="ngModel"
required>
<option value="">Choose...</option>
<option *ngFor="let genre of genres;" [value]="genre.value">{{genre.name}}</option>
</select>
This is the field that binded with template from my Component:
// Genres of films like action or drama that will populate dropdown list.
genres: Genre[];
I fetch genres of films from server dynamically. In order do communicate with server I have created FilmService
This is the method which communicate server:
fetchGenres(): Observable<Genre[]> {
return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>;
}
Why this method returns Observable<Genre[]>
not something like Genre[]
?
JavaScript is async
and it does not wait for a method to return value after an expensive process. With expensive I mean a process that take a time to return value. Like fetching data from server. So you have to return reference of Observable and subscribe it.
For example in my Component :
ngOnInit() {
this.filmService.fetchGenres().subscribe(
val => this.genres = val
);
}