MobX - Filter asMap from computed value?

721 views Asked by At

I am trying asMap and want to output the book titles that match the coverType:

Here is the BookStore:

class BookStore {
    @observable coverType = 'soft';
    @observable booksByIdMap = asMap({
      "88cd7621": {
        "id": "88cd7621",
        "title": "The Secret",
        "coverType": 'soft'
      },
      "88cd7622": {
        "id": "88cd7622",
        "title": "The Alchemist",
        "coverType": 'hard'
      },
      "88cd7623": {
        "id": "88cd7623",
        "title": "Javascript",
        "coverType": 'soft'
      }
    });

    @computed get byCoverType() {
      return this.booksByIdMap.filter(book => book.coverType == this.coverType);
    }
}

Here is the UI:

const bookStore = new BookStore();

const BookViewItem = observer(({book}) => 
    <li>
        {book.title}
    </li>
);

@observer
class BookView extends Component {
  render() {
    return <div>
      <h1>Books With Cover Type: {bookStore.coverType}</h1>
      <ul>
        {bookStore.byCoverType().map(book => 
          <BookViewItem book={book} key={book.id} />
         )}
      </ul>
     </div>
  }
}

But it does not render the book titles based on the current coverType value.

Here is a fiddle: https://jsfiddle.net/ob7v1gk5/

How can I output the book titles using the computed Bookstore.byCoverType filtered results?

1

There are 1 answers

3
Tholle On BEST ANSWER

A MobX map is not an array, so it does not have filter and other array specific methods. Check the documentation to see what methods you can use.

You could e.g. use the values method and then use filter on the resulting array like this:

class BookStore {
  @observable coverType = 'soft';
  @observable booksByIdMap = asMap({
    "88cd7621": {
      "id": "88cd7621",
      "title": "The Secret",
      "coverType": 'soft'
    },
    "88cd7622": {
      "id": "88cd7622",
      "title": "The Alchemist",
      "coverType": 'hard'
    },
    "88cd7623": {
      "id": "88cd7623",
      "title": "Javascript",
      "coverType": 'soft'
    },
  });

  @computed get byCoverType() {
    return this.booksByIdMap.values().filter(b => b.coverType === this.coverType);
  }
}