[英]Angular 8 Type 'void' is not assignable to type 'ObservableInput<any>'
[英]How to solve `(logList: string[]) => void' is not assignable to parameter of type '(value: string[], index: number) => ObservableInput<any>`?
我有一個問題,要從兩個 observable 中創建一個 observable 對象並保持第一個 observable 的順序。 正如您在示例中看到的,目標是按日期對可觀察對象進行排序。
看起來問題出在ngOnInit()
因為我在concatMap(logList => {
:
TS2345: Argument of type '(logList: string[]) => void' is not assignable to parameter of type '(value: string[], index: number) => ObservableInput<any>'. Type 'void' is not assignable to type 'ObservableInput<any>'.
我正在使用concatMap
因為否則有時我會dailyLogs
順序不正確的問題。
我已經嘗試並搜索了很多,但是一天多之后,我找不到任何可以擺脫此錯誤消息的方法。 奇怪的是,即使有這個錯誤,它有時也會編譯,然后結果是正確的。
在concatMap
使用return
也不起作用 => return dailyLogs.push({logs: logList, date});
我究竟做錯了什么?
以下是我的示例代碼:
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
dailyLogs$: Observable<{logs: string[], date: Date}[]>;
constructor(
private readonly logService: LogService,
private readonly dateService: DateService
) {
}
ngOnInit(): void {
this.dailyLogs$ = this.dateService.getDates()
.pipe(
map(values => {
const dates = Array<Date>();
values.forEach(value => {
if (value) {
dates.push(value);
}
});
return dates;
}),
map(dates => {
const dailyLogs = Array<{logs: string[], date: Date}>();
dates.forEach(date => {
this.logService.findLogsByDate(date)
.pipe(
concatMap(logList => {
dailyLogs.push({logs: logList, date});
})
).subscribe();
});
return dailyLogs;
})
);
}
}
應用程序組件.html
<ng-container *ngIf="dailyLogs$">
<div *ngFor="let i of [0, 1, 2]">
<table>
<tr>
<th>Logs</th>
</tr>
<tr *ngFor="let log of (dailyLogs$ | async)[i].logs">
<td>{{log}}</td>
</tr>
</table>
<br>
</div>
</ng-container>
日志.service.ts
@Injectable({
providedIn: 'root'
})
export class LogService {
firstLogs = [
'Log 1',
'Log 2',
'Log 3',
'Log 4'
];
secondLogs = [
'Log 5',
'Log 6',
'Log 7',
'Log 8',
'Log 9',
'Log 10',
'Log 11'
];
thirdLogs = [
'Log 12',
'Log 13'
];
findLogsByDate(date: Date): Observable<string[]> {
const dateString = date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2);
if (dateString === '2019-12-17') {
return of(this.firstLogs);
} else if (dateString === '2019-12-16') {
return of(this.secondLogs);
} else if (dateString === '2019-12-13') {
return of(this.thirdLogs);
}
}
}
日期.service.ts
@Injectable({
providedIn: 'root'
})
export class DateService {
firstDate = new Date('2019-12-17');
secondDate = new Date('2019-12-16');
thirdDate = null;
fourthDate = null;
fifthDate = new Date('2019-12-13');
getDates(): Observable<Date[]> {
return of([
this.firstDate,
this.secondDate,
this.thirdDate,
this.fourthDate,
this.fifthDate
]);
}
}
您不應該在map
函數內訂閱。 嘗試使用switchMap
並切換到一個 Observable,將結果組合成一個新的 Observable,如下所示:
ngOnInit(): void {
this.dailyLogs$ = this.dateService.getDates()
.pipe(
map(values => values.filter(value => !!value)), // User filter to get only truthy dates
switchMap(dates => combineLatest( // switch to a combined observable of all 'findLogsByDate' calls and map each to the desired output
dates.map(date => this.logService.findLogsByDate(date)
.pipe(
map(logList => ({logs: logList, date}))
)
)
))
);
}
這是一個有效的StackBlitz 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.