web-dev-qa-db-ja.com

Angular2:配列をObservableに変換します

Http経由でサービスからデータを取得するコンポーネントがあります。問題は、このコンポーネントを表示するたびにAPIバックエンドにアクセスしたくないことです。データがメモリにあるかどうかをチェックし、メモリにある場合はメモリ内の配列でオブザーバブルを返し、そうでない場合はhttpリクエストを作成します。

私のコンポーネント

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

私のサービス

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');
  }
}
50
Mathius17

あなたはすぐそこにいます。既にメモリにデータがある場合は、 of observableを使用できます(RxJS 4の return/just と同等)。

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);
    }
}
70
Eric Martinez
import { of } from 'rxjs';


return of(this.contacts);
13
Mo D Genesis

私のような一部の人は、string[]からObservable<string>に変更することを望んでいます。

これは、変換を伴う例です。

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

うまくいけば、他の人にも役立つでしょう。

8
sancho21

Angle7では、of()を置くだけで十分です。 of()の中に置くものはすべて、監視可能に変更されます。ここで、this.contactsは監視可能に変換されます。

import { of } from 'rxjs'; 

getContacts() {

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

Observable.of(resultArray);を使用することもできます

import { Observable } from 'rxjs;'パッケージから

0
Ali

これは非常に遅れる可能性がありますが、作業の一部を処理するためにsessionStorageをかなり頻繁に使用しています。人が跳ね回っていたために状態を失っても、データは残っています。

 getSubjects(): Observable<Subject[]> {
   
    let SubjectsString = sessionStorage.getItem("Subjects")

    if (SubjectsString) {
      let subjects: Subject[] = JSON.parse(SubjectsString);
      console.log("GETTING DATA FROM SESSION STORAGE")
      return Observable.of(subjects);
      
    } else {
      let url = `${this.apiHost}/api/subject`;
      return this.http.get(url)
        .map(res =>{          
    
          sessionStorage.setItem("Subjects",JSON.stringify(res.json()));           
          return res.json();
        })
      
      
    }

       
  }

この例では、SubjectのクラスとapiHostの定義がありますが、残りは非常に簡単です。オブザーバブルのサービスを呼び出します。コンポーネントにはデータの場所がわからないため、気にしません。サービスはローカルストレージをチェックし、保持している場合はオブザーバブルに変換して返し、保持していない場合は取得して取得し、ローカルストレージに保存してから返します。

私の場合、数百ページの巨大なアプリケーションがあります。ユーザーは、素敵な新しいAngular4ページからクラシックASP年齢に戻って何度もバウンスする可能性があります。セッションストレージにすべてのメニュー項目と検索結果を含めることは、命の恩人です。

0
Daniel Morris

クイックソリューションはこちら:

getSomething():Observable<Object[]>{
        return new Observable(observable => {
            this.http.get('example.com').subscribe(results => {
                observable.next(results.json());
                observable.complete();
            });
        });
    }
0
Mr.Zon