Angular에서 http와 유사한 정적 데이터에서 Observable을 만드는 방법은 무엇입니까?


121

이 방법이있는 서비스가 있습니다.

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

구성 요소의 생성자에서 다음과 같이 구독하고 있습니다.

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

이것은 객체가 서버에서 온 경우 작동하지만 subscribe()정적 문자열에 대한 주어진 호출 ( testModelService.fetchModel()uuid를받지 못할 때 발생 함) 과 함께 작동하는 관찰 가능 항목을 만들려고 하므로 두 경우 모두 원활하게 처리됩니다.

답변:


151

아마도 클래스 의 of메소드를 사용해 볼 수 있습니다 Observable.

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

2
그것은 굉장했다! 작동했습니다! 나는 Observable.from () 등과 같은 많은 것들을 시도하고 있었다. Observable에 대한 API 문서는이 시점에서 가장 깨끗하고 사용자 친화적이지 않다! 감사합니다 :)
Michail Michailidis

45
당신이 버전 6을 사용하는 경우 한 가지, 당신은로했습니다 import { of } from 'rxjs';사용 of대신에, Observable.of.
vip

2
Angular v7.xx의 경우 .map()get의 결과 가 없으므로 수행해야합니다 .pipe(map((res:any) => res.json())). 여기를 참조하십시오 : stackoverflow.com/a/35220045/986160
Michail Michailidis

64

2018 년 7 월 및의 릴리스 RxJS 6부터 값에서 Observable을 가져 오는 새로운 방법은 of다음과 같이 연산자 를 가져 오는 것입니다.

import { of } from 'rxjs';

다음과 같이 값에서 관찰 가능 항목을 만듭니다.

of(someValue);

Observable.of(someValue)현재 허용되는 답변에서 같은 작업을 수행해야했습니다 . 다른 RxJS 6 변경 사항에 대한 좋은 기사가 여기에 있습니다 .


정말 감사합니다.이 작동합니다
Sarah

19

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

.next()함수는 가입자에게 호출됩니다.


2
Angular 2.1.2로 마이그레이션했습니다. 이전 방식은 여전히 ​​지원되는 것 같습니다. 왜 이것이 더 나은 솔루션인지 아니면 컨벤션인지 설명해 주시겠습니까? 그런 다음 코드의 모든 위치에서 변경하고 다시 수락하겠습니다. ..Thanks
Michail Michailidis

7
@MichailMichailidis, 한 달 동안 회고 해보니 둘 다 똑같이 유효한 것 같습니다. 주요 차이점은 Thierry의 솔루션이 ofrxjs 의 기능을 가져와야한다는 것입니다.import 'rxjs/add/observable/of'
Niel de Wet

12

이것이 정적 데이터에 대한 간단한 관찰 가능 항목을 만드는 방법입니다.

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

이 답변이 도움이 되었기를 바랍니다. 정적 데이터 대신 HTTP 호출을 사용할 수 있습니다.


당신은 observable.subscripe에서 observable.subscribe에 오타를 업데이트 할 수 있습니다
Sudharshan

3

이렇게하면 데이터에서 Observable을 만들 수 있습니다. 제 경우에는 장바구니를 유지해야합니다.

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;
        });
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.