如何解决`(logList:string [])=> void'不能分配给'(value:string [],index:number)=> ObservableInput <any>`类型的参数?

康斯坦丁啤酒

我有一个问题,要从两个可观察对象中创建一个可观察对象,并保持第一个可观察对象的顺序。在示例中可以看到,目标是按日期对可观察对象进行排序。

看来问题出在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顺序不正确。

我已经尝试了很多,但进行了很多搜索,但是经过一天多的时间,我找不到任何摆脱该错误消息的方法。奇怪的是,即使出现此错误,有时也会编译,然后结果是正确的。

另外return在里面使用没用concatMap=>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;
        })
      );
  }
}

app.component.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>

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

date.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
    ]);
  }
}
Pascalpuetz

您不应该在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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章