How to use map and assign the value back

时光毁灭记忆、已成空白 提交于 2019-12-11 04:21:47

问题


I have a list of books, with IsEnable default to False. I need to check each book whether its enabled or not in onInit(). I thought of adding a rxjs map and call the getEligibleBooks() function inside the map, but how to assign the return value true or false in the IsEnable?

Books.ts

export class Book{
Name:string;
IsEnable:boolean;
}

books.component.ts

...
books = Observable.of([{"Name":"A", "IsEnable":"False"},{"Name":"B", "IsEnable":"False"}]);
...
getEligibleBooks(book){
//complex logic
return result; //true or false
}
...
ngOnInit(){
this.books.pipe(
    map( book => this.getEligibleBooks(book)) // have no idea how to achieve it
  ).subscribe(data=>console.log(data));
}

回答1:


  • As you are not actually changing the returned type anywhere there is no need to use map. It seems all you want to do is iterate over the returned result and possibly set a member on a book instance. In that case use tap instead of map. map is useful when you want to transform the input into a different output.
  • The code needs to make a distinction between an array and an object when performing an operation. That becomes easier to see when you define expected types in your method signatures for both inputs (method arguments) and the return type. The same goes for the naming of arguments, use plural form for arrays and singular form for non-array types. In this case use books and book.
  • I would recommend using an interface over a class as you have no defined behavior. This is simpler when mapping parsed json to a type.
  • Note that the constant boolean values are true and false, do not assign "True" / "False" as these are string literals and not boolean values. If you do a truthy comparison on "False" it will evaluate to true

Books.ts

export interface IBook{
    Name:string;
    IsEnable:boolean;
    IsEligible?:boolean|undefined;
}

books.component.ts

books: IBook[];

getBooksAsync() : Observable<IBook[]> {
  return Observable.of([{"Name":"A", "IsEnable":false},{"Name":"B", "IsEnable":false}] as IBook[]);
}

isBookEligible(book: IBook): boolean {
  return true; // hard coded for now because there is no implementation
}

ngOnInit(){
    this.getBooksAsync.pipe(
        tap((books) => {
            books.forEach((book) => book.IsEligible = this.isBookEligible(book));
        })
    ).subscribe(books => this.books = books);
}



回答2:


You can try this

this.books.pipe(
    map( book => {
     book.IsEnable = this.getEligibleBooks(book); 
     return book
    }) 
).subscribe( data => console.log(data) );



回答3:


Rxjs of operator streams whole table at once. Rxjs map operator is mapping whole table to the new output. When you want to change items in the table you need to also use js map function to mutate whole table by checking all of the table items separately.

this.books.pipe(
      map(
        books => books.map( book => { ...book, IsEnable: this.getEligibleBooks(book) })),
    ).subscribe(data => console.log(data));


来源:https://stackoverflow.com/questions/55374349/how-to-use-map-and-assign-the-value-back

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!