Using different buttons based on object array result


#1

Hi All,

I have a field/property on one of my collections that stores all of the people that “own” a copy of that game. Basically what I want to be able to do in a list of all the games is show buttons to either prompt the user to add (or remove) the game to their list of owned games - i.e. if my user IS NOT in the array field “owns” it will show me the button to add the game to my list (pushing my user id into that array) OR if my user IS in the array field “owns” it will show me the button to remove the game from my list (pulling my user from that array). I already have the arrays and everything else working, just not the flicking between.

Below is the collection code setting up the array field;

owns: {
    type: Array,
    label: 'People who own this game.',
    optional: true,
  },
  'owns.$': {
    type: String,
},

So I thought I could something like this;

{ {owns} ? //am I calling this right? how do i tell if the user is in this array?
	<Button
		bsStyle="primary"
		onClick={() => handleAddOwn(_id)}
		block
	>
		Add the Shelf
	</Button>
	: <Button
		bsStyle="primary"
		onClick={() => handleAddOwn(_id)}
		block
	>
		Remove from my shelf
	</Button>}

I am just not sure how to determine if “own” is true - i.e. if the user is in the array of the field returned.

Games.propTypes = {
  loading: PropTypes.bool.isRequired,
  games: PropTypes.arrayOf(PropTypes.object).isRequired,
  match: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
};

export default withTracker(() => {
  const subscription = Meteor.subscribe('games');
  return {
    loading: !subscription.ready(),
    games: GamesCollection.find().fetch(),
  };
})(Games);
         {games.map(({
            _id, title, rrp, edition, pubYear, publisher, wishlist, owns
          }) => (
            <tr key={_id}>
            <td>{title}</td>
            etc.

#2

Easiest thing I can think of is to use:

owns.includes(Meteor.userId())

or mapping over the collection in withTracker before passing props:

export default withTracker(() => {
  const subscription = Meteor.subscribe('games');
  const userId = Meteor.userId();
  return {
    loading: !subscription.ready(),
    games: GamesCollection.find().map(game => {
      return {
        ...game,
        owns: game.owns.includes(userId),
      };
    }),
  };
})(Games);

At which point instead of replacing the owns field you could add a new one ownedByUser or whatever you wanted