Wie erstelle ich ein Observable aus statischen Daten, die http one in Angular ähneln?

121

Ich habe einen Dienst mit dieser Methode:

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

Im Konstruktor der Komponente abonniere ich Folgendes:

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

Dies funktioniert, wenn ein Objekt vom Server stammt, ich jedoch versuche, ein Observable zu erstellen, das mit dem angegebenen subscribe()Aufruf einer statischen Zeichenfolge testModelService.fetchModel()funktioniert (dies geschieht, wenn keine UUID empfangen wird), sodass in beiden Fällen eine nahtlose Verarbeitung erfolgt.

Michail Michailidis
quelle

Antworten:

151

Vielleicht könnten Sie versuchen, die ofMethode der ObservableKlasse zu verwenden:

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
quelle
2
Das war wunderbar! Es funktionierte! Ich habe viele Dinge wie Observable.from () usw. ausprobiert. Die API-Dokumentation für Observable ist derzeit nicht die sauberste / benutzerfreundlichste! Danke :)
Michail Michailidis
44
Eine Sache, wenn Sie Version 6 verwenden, müssen import { of } from 'rxjs';und verwenden of, anstatt Observable.of.
VIP
2
Für Angular v7.xx gibt es keine .map()Ergebnisse für get, daher müssen Sie dies tun .pipe(map((res:any) => res.json())). Siehe hier: stackoverflow.com/a/35220045/986160
Michail Michailidis
62

Ab Juli 2018 und der Veröffentlichung von RxJS 6besteht die neue Möglichkeit, ein Observable aus einem Wert zu erhalten, darin, den ofOperator wie folgt zu importieren :

import { of } from 'rxjs';

und erstellen Sie dann das Observable aus dem Wert wie folgt:

of(someValue);

Beachten Sie, dass Sie früher Observable.of(someValue)wie in der aktuell akzeptierten Antwort vorgehen mussten. Es gibt einen guten Artikel über die anderen RxJS 6 Änderungen hier .

VSO
quelle
Vielen Dank, das funktioniert
Sarah
19

Die Dinge scheinen sich seit Angular 2.0.0 geändert zu haben

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

Die .next()Funktion wird auf Ihrem Teilnehmer aufgerufen.

Niel de Wet
quelle
2
Ich bin auf Angular 2.1.2 migriert. Der alte Weg scheint immer noch unterstützt zu werden. Könnten Sie bitte erläutern, warum dies eine bessere Lösung ist oder ob es sich um die Konvention handelt? Ich werde es dann an allen Stellen in meinem Code ändern und ich werde es wieder akzeptieren. Danke
Michail Michailidis
7
@MichailMichailidis, mit einem Monat Rückblick, scheint es mir, dass beide gleichermaßen gültig sind, der Hauptunterschied besteht darin, dass Thierrys Lösung erfordert, dass Sie die ofFunktion von rxjs importieren, wieimport 'rxjs/add/observable/of'
Niel de Wet
12

Auf diese Weise können Sie eine einfache Observable für statische Daten erstellen.

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

Ich hoffe diese Antwort ist hilfreich. Wir können stattdessen statische Daten über einen HTTP-Aufruf verwenden.

Balwant Padwal
quelle
können Sie den Tippfehler von Observable.subscripe auf Observable.subscribe
aktualisieren
3

Auf diese Weise können Sie Observable aus Daten erstellen. In meinem Fall muss ich den Warenkorb pflegen:

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
quelle