Bagaimana cara membuat Observable dari data statis yang mirip dengan http di Angular?

121

Saya memiliki layanan yang memiliki metode ini:

export class TestModelService {

    public testModel: TestModel;

    constructor( @Inject(Http) public http: Http) {
    }

    public fetchModel(uuid: string = undefined): Observable<string> {
        if(!uuid) {
            //return Observable of JSON.stringify(new TestModel());
        }
        else {
            return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
                .map(res => res.text());
        }
    }
}

di konstruktor komponen saya berlangganan seperti ini:

export class MyComponent {
   testModel: TestModel;
   testModelService: TestModelService;

   constructor(@Inject(TestModelService) testModelService) {
      this.testModelService = testModelService;

      testService.fetchModel("29f4fddc-155a-4f26-9db6-5a431ecd5d44").subscribe(
          data => { this.testModel = FactModel.fromJson(JSON.parse(data)); },
          err => console.log(err)
      );
   }
}

Ini berfungsi jika sebuah objek berasal dari server tetapi saya mencoba membuat observable yang akan bekerja dengan subscribe()panggilan yang diberikan untuk string statis (ini terjadi ketika testModelService.fetchModel()tidak menerima uuid) sehingga ada penanganan yang mulus dalam kedua kasus.

Michail Michailidis
sumber

Jawaban:

151

Mungkin Anda dapat mencoba menggunakan ofmetode Observablekelas:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

public fetchModel(uuid: string = undefined): Observable<string> {
  if(!uuid) {
    return Observable.of(new TestModel()).map(o => JSON.stringify(o));
  }
  else {
    return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
            .map(res => res.text());
  }
}
Thierry Templier
sumber
2
Itu luar biasa! Berhasil! Saya mencoba banyak hal seperti Observable.from () dll. Dokumentasi API untuk Observable bukanlah yang terbersih / paling ramah pengguna saat ini! Terima kasih :)
Michail Michailidis
45
Satu hal jika Anda menggunakan versi 6, Anda harus import { of } from 'rxjs';dan menggunakan of, bukan Observable.of.
vip
2
Untuk Angular v7.xx tidak ada .map()hasil get jadi Anda perlu melakukannya .pipe(map((res:any) => res.json())). Lihat di sini: stackoverflow.com/a/35220045/986160
Michail Michailidis
64

Mulai Juli 2018 dan rilis RxJS 6, cara baru untuk mendapatkan Observable dari suatu nilai adalah dengan mengimpor ofoperator seperti ini:

import { of } from 'rxjs';

dan kemudian buat yang dapat diamati dari nilainya, seperti:

of(someValue);

Perhatikan, bahwa Anda dulu harus melakukan Observable.of(someValue)seperti dalam jawaban yang diterima saat ini. Ada artikel bagus tentang perubahan RxJS 6 lainnya di sini .

VSO
sumber
Terima kasih banyak, ini berhasil
Sarah
19

Hal-hal tampaknya telah berubah sejak Angular 2.0.0

import { Observable } from 'rxjs/Observable';
import { Subscriber } from 'rxjs/Subscriber';
// ...
public fetchModel(uuid: string = undefined): Observable<string> {
  if(!uuid) {
    return new Observable<TestModel>((subscriber: Subscriber<TestModel>) => subscriber.next(new TestModel())).map(o => JSON.stringify(o));
  }
  else {
    return this.http.get("http://localhost:8080/myapp/api/model/" + uuid)
            .map(res => res.text());
  }
}

The .next()fungsi akan dipanggil pelanggan Anda.

Niel de Wet
sumber
2
Saya telah bermigrasi ke Angular 2.1.2 .. Cara lama sepertinya masih didukung .. Bisakah Anda menjelaskan mengapa ini adalah solusi yang lebih baik atau konvensi? Saya kemudian akan mengubahnya di semua tempat di kode saya dan saya akan menerimanya kembali .. Terima kasih
Michail Michailidis
7
@MichailMichailidis, dengan satu bulan retrospeksi, menurut saya keduanya sama-sama valid, perbedaan utamanya adalah solusi Thierry mengharuskan Anda untuk mengimpor offungsi rxjs, sepertiimport 'rxjs/add/observable/of'
Niel de Wet
12

Ini adalah bagaimana Anda dapat membuat observasi sederhana untuk data statis.

let observable = Observable.create(observer => {
  setTimeout(() => {
    let users = [
      {username:"balwant.padwal",city:"pune"},
      {username:"test",city:"mumbai"}]

    observer.next(users); // This method same as resolve() method from Angular 1
    console.log("am done");
    observer.complete();//to show we are done with our processing
    // observer.error(new Error("error message"));
  }, 2000);

})

to subscribe to it is very easy

observable.subscribe((data)=>{
  console.log(data); // users array display
});

Saya harap jawaban ini bermanfaat. Kita bisa menggunakan panggilan HTTP sebagai pengganti data statis.

Balwant Padwal
sumber
dapatkah Anda memperbarui kesalahan ketik dari observable.subscripe menjadi observable.subscribe
Sudharshan
3

Dengan cara ini Anda dapat membuat Observable from data, dalam kasus saya, saya perlu mengelola keranjang belanja:

service.ts

export class OrderService {
    cartItems: BehaviorSubject<Array<any>> = new BehaviorSubject([]);
    cartItems$ = this.cartItems.asObservable();

    // I need to maintain cart, so add items in cart

    addCartData(data) {
        const currentValue = this.cartItems.value; // get current items in cart
        const updatedValue = [...currentValue, data]; // push new item in cart

        if(updatedValue.length) {
          this.cartItems.next(updatedValue); // notify to all subscribers
        }
      }
}

Component.ts

export class CartViewComponent implements OnInit {
    cartProductList: any = [];
    constructor(
        private order: OrderService
    ) { }

    ngOnInit() {
        this.order.cartItems$.subscribe(items => {
            this.cartProductList = items;
        });
    }
}
Rahul Dadhich
sumber