Аргумент типа x не может быть назначен параметру типа '(x) => ObservableInput <{}> - PullRequest
0 голосов
/ 28 июня 2018

надеюсь, кто-то может пролить свет на это

Работа с ngrx и попытка использовать несколько switchMaps для вызова некоторых классов действий.

Мои действия:

export class BlogAddedAction implements Action {

    readonly type = BLOG_ADDED_ACTION;

    constructor(public payload:any) {

    }

}
export class CrudSucessAction implements Action {

    readonly type = CRUD_SUCCESS_ACTION;

    constructor(public payload:any) {

    }
}

export class BlogAddedToDBAction implements Action {

    readonly type = BLOG_ADDED_TO_DB_ACTION;

    constructor(public payload:any) {

    }
}

effects.ts:

  @Effect() addBlog$: Observable<any> = this.actions$
  .ofType<BlogAddedAction>(BLOG_ADDED_ACTION)
    .switchMap(action =>  {
        console.log(action)
    return this.blogService.addBlog(action.payload.blog)
    })
    .switchMap((action)=>new BlogAddedToDBAction(action))
    .map((action)=>new CrudSucessAction(action))
}

Но я получаю ошибку Typescript:

[ts]
Argument of type '(action: Blog) => BlogAddedToDBAction' is not 
assignable to parameter of type '(value: Blog, index: number) => ObservableInput<{}>'.Type 'BlogAddedToDBAction' is not assignable to type 'ObservableInput<{}>'.
Type 'BlogAddedToDBAction' is not assignable to type 'ArrayLike<{}>'.Property 'length' is missing in type 'BlogAddedToDBAction'.

Попытка использовать карту вместо второго switchMap, но BlogAddedToDBAction не выполняется.

1 Ответ

0 голосов
/ 28 июня 2018

switchMap следует использовать, когда вы хотите создать Observable, который вы можете отменить - в этом случае это addBlog http-запрос. В этом случае вы, скорее всего, захотите mergeMap вместо этого, поскольку, если вы попытаетесь добавить блог до того, как предыдущий блог будет закончен, он будет отменен. Смотри: https://blog.angularindepth.com/switchmap-bugs-b6de69155524

switchMap требует, чтобы было выдано совместимое с Observable значение, поэтому вы не можете вернуть простой объект, такой как BlogAddedToDBAction. Вместо этого вы можете сделать of(new BlogAddedToDBAction(action)), поскольку of создаст Observable, который испускает этот объект - однако это может быть не то, что вы хотите.

Effect - это отдельный наблюдаемый поток, который испускает действия. Ваш поток только излучает CrudSuccessAction.

Кажется, вы, вероятно, хотите испустить оба действия. Для этого вы можете использовать merge. Тогда наблюдаемый эффект будет испускать каждое действие в последовательности. Я бы написал так:

@Effect() addBlog$: Observable<any> = this.actions$.pipe(
  ofType<BlogAddedAction>(BLOG_ADDED_ACTION),
  mergeMap(action =>  {
    console.log(action)
    return this.blogService.addBlog(action.payload.blog).pipe(
      mergeMap(action => [new BlogAddedToDBAction(action), new CrudSucessAction(action)]),
      catchError(() => of(new CrudErrorAction())
  });

mergeMap с массивом будет выдавать каждое значение массива. Вы можете подтвердить это с помощью простого теста:

of(1).pipe(mergeMap(() => [1, 2])).subscribe(console.log); // logs 1, then 2
...