[英]Getting error when calling a method inside observable which returns another observable
I am new to angular and observable.我是 angular 和 observable 的新手。 I have tried flatMap, swithMap and concatMap, but nothing helps.我尝试过 flatMap、swithMap 和 concatMap,但没有任何帮助。 I have got the error " You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable ."我收到错误消息“您在需要流的地方提供了 'undefined'。您可以提供 Observable、Promise、Array 或 Iterable 。” When the code of switch case 1 runs of inputprocessing method,while the default case works completely fine.当 switch case 1 的代码运行 inputprocessing 方法时,而 default case 完全正常。
app.component.ts app.component.ts
export class AppComponent implements OnInit, AfterViewChecked, OnChanges {
ProcessInput(input: string, session: string): void {
this.appService
.ProcessInput(input, session)//this works fine and returns the response.
.pipe(
concatMap((res: any) => {
return this.inputProcessing.inputProcessing(res);
})
)
.subscribe(
res => {
this.arr.push("TEST");
},
err => {
console.log(err);
}
);
}
}
inputprocessing.service.ts inputprocessing.service.ts
import "reflect-metadata";
import { Injectable } from "@angular/core";
import { Container, inject, injectable, AsyncContainerModule } from "inversify";
import { OutputResponse } from "../response";
import { PrescriptionStatus } from "src/Classes/PrescriptionStatus";
import { service } from "./service.service";
import { HttpClient } from "@angular/common/http";
import { CourierMode } from "../enums/CourierMode";
import { Observable, of } from "rxjs";
import { switchMap, flatMap, concatMap } from "rxjs/operators";
import { PrescriptionStatusMain } from "src/models/PrescriptionStatusResponse";
@Injectable({
providedIn: "root"
})
export class InputprocessingService {
constructor(private service: service,private http: HttpClient) {}
responseText: string;
returnMessage: string;
inputProcessing(response: OutputResponse): Observable<any> {
this.responseText = response.output.generic[0].text;
//works completely fine with default case, but when case 1: runs it gave an error
switch (this.responseText) {
case "1": {
const obsFail = new Observable(observer => {
observer.next(this.returnMessage);
observer.error();
observer.complete();
});
this.service.getStatus().pipe(
concatMap((res: StatusMain) => {
return obsFail ;
})
);
break;
}
default: {
const obs = new Observable(observer => {
observer.next(this.responseText);
observer.complete();
});
return obs;
}
}
}
}
service.ts服务.ts
import * as request from "request";
import * as request_promise from "request-promise-native";
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { StatusMain } from "src/models/StatusResponse";
import { Observable } from "rxjs";
@Injectable()
export class service {
constructor(private http: HttpClient) {}
getStatus(): Observable<StatusMain> {
const body = { bdate: "1999/05/01" };
return this.http.post<StatusMain>(
"http://localhost:49995/api/Status",
body
);
}
}
inputProcessing
function in your service needs to return an observable.您服务中的inputProcessing
函数需要返回一个 observable。 With your implementation the created observable only emits the value, while the concatMap
expects an observable.在您的实现中,创建的 observable 只发出值,而concatMap
需要一个 observable。 Hence the error: You provided 'undefined' where a stream was expected.因此出现错误:您在需要流的地方提供了“未定义”。 You can provide an Observable, Promise, Array, or Iterable.您可以提供 Observable、Promise、Array 或 Iterable。
Try this:尝试这个:
export class AppComponent implements OnInit, AfterViewChecked, OnChanges {
ProcessInput(input: string, session: string): void {
this.appService
.ProcessInput(input, session)//this works fine and returns the response.
.pipe(
flatMap((res: any) => {
return this.inputProcessing.inputProcessing(res);
})
)
.subscribe(
res => {
this.arr.push("TEST");
},
err => {
console.log(err);
}
);
}
}
And in your service:在您的服务中:
@Injectable({
providedIn: "root"
})
export class InputprocessingService {
constructor(private service: service,private http: HttpClient) {}
responseText: string;
returnMessage: string;
inputProcessing(response: OutputResponse): Observable<any> {
this.responseText = response.output.generic[0].text;
let returnObservable;
//works completely fine with default case, but when case 1: runs it gave an error
switch (this.responseText) {
case "1": {
const obsFail = new Observable(observer => {
observer.next(this.returnMessage);
observer.error();
observer.complete();
});
returnObservable = this.service.getStatus().pipe(
concatMap((res: StatusMain) => {
return obsFail ;
})
);
break;
}
default: {
returnObservable = new Observable(observer => {
observer.next(this.responseText);
observer.complete();
});
}
}
return returnObservable;
}
}
Note how AppComponent
implements flatMap
.注意AppComponent
如何实现flatMap
。 flatmap
must return an observable. flatmap
必须返回一个 observable。 Hence inputProcessing
creates a local variable ( returnObservable
) which holds a reference to different observables (switch statement: case1, case2... default).因此inputProcessing
创建了一个局部变量( returnObservable
),它保存对不同 observable 的引用(switch 语句:case1, case2... default)。
When the inner observables emit value, then returnObservable
emits that value to the outer flatMap
.当内部 observable 发出值时, returnObservable
将该值发送到外部flatMap
。
inputprocessing.service.ts This code resolved the issue. inputprocessing.service.ts这段代码解决了这个问题。
@Injectable({
providedIn: "root"
})
export class InputprocessingService {
constructor(private service: service,private http: HttpClient) {}
responseText: string;
returnMessage: string;
inputProcessing(response: OutputResponse): Observable<any> {
this.responseText = response.output.generic[0].text;
let returnObservable;
//works completely fine with default case, but when case 1: runs it gave an error
switch (this.responseText) {
case "1": {
//This line solved the error.
return this.service.getStatus().pipe(map(res=>{return res}));
break;
}
default: {
returnObservable = new Observable(observer => {
observer.next(this.responseText);
observer.complete();
});
}
}
return returnObservable;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.