Можно ли сохранить наблюдаемые данные в другую наблюдаемую - PullRequest
0 голосов
/ 12 мая 2018

Я пытался получить массив имен из наблюдаемой ниже, чей ответ исходит от API (здесь жестко задан). Я хочу сохранить исходные данные в другой наблюдаемой.Итак, что я реализовал:

this.initialData=Observable.of({
      data: [
        {
          firstName: 'steve',
          lastName: 'jobs'
        },
        {
          firstName: 'steve1',
          lastName: 'jobs1'
        }
      ]
    })   .map(res => {
        this.wantToAchieveObs$ = Observable.of(res.data);
        return res.data; 
      })
      .switchMap(dataArray => {
        return from(dataArray);
      })
      .bufferCount(5)
      .map((singleArray: any) => {
        return singleArray.map(_ => _.firstname);
      })

Но я не получаю наблюдаемого от wantToAchieveObs $, и я не хочу, чтобы API снова ударил по этим же данным снова.Это достижимо любым другим способом, так как я пытаюсь использовать это наблюдаемое и в методе combLatest.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

Что вам, вероятно, нужно, это использовать BehaviorSubject в вашем сервисе. Это немного зависит от того, что вы хотите сделать, но вы можете сделать что-то вроде этого:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
// Your imports might be different if you use angular 6
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/filter';

@Injectable()
export class Service {

    // We use this variable to find out if a request to the backend has already been issued.
    private _hasRequested = false;
    // The behavior subject will keep track of the data
    private _subject: BehaviorSubject<any>;
    // This is the observable with the data. You should not expose the subject directly
    // all you want is to expose an observable.
    private _data$: Observable<any>;

    constructor(private http: HttpClient) {
        // BehaviourSubjects need an initial value. We can use undefined
        this._subject = new BehaviorSubject<any>(undefined);
        // Map the subject into an observable.
        this._data$ = this._subject
            .asObservable()
            // We filter out undefined values as we only want to be notified when there is data
            .filter(data => data !== undefined);
    }

    // This method can be used by users of the service.
    // getData().subscribe() will issue a call to the backend when it is called for
    // the first time.
    getData(): Observable<any> {
        // Check if a backend request has already been issued
        if (!this._hasRequested) {
            // If not, issue a request and change the flag to true, so we don't do this again
            this.refresh();
            this._hasRequested = true;
        }
        // Return the data observable
        return this._data$;
    }

    // In case you need to refresh the data that has been loaded, you
    // can use the refresh method to get a newer value from the backend
    refresh() {
        this.http.get('path/to/data')
        .subscribe(
            response => this._subject.next(response),
            error => this._subject.error(error)
        );
    }

}
0 голосов
/ 12 мая 2018

Вы можете попробовать что-то вроде следующего:

const cached$ = wantToAchieveObs$.shareReplay(1);

Теперь вы можете использовать cached$ вместо wantToAchieveObs$.

Последнее значение из wantToAchieveObs$ всегда сохраняется вcached$.

Если вы хотите сохранить больше значений, используйте что-то вроде shareReplay(2) для хранения последних 2 значений.

...