Adding Memberships to the Front End
- Chuck Curtis

- Sep 9, 2019
- 4 min read
Now that I've added memberships to the rails back end, it's time to add the feature to the front end. I'll start in the individual Group component, and then update my other components along the way.
With the addition of Memberships, I now have four conditions for the Group component. First, if there is no user (viewing the Group component without being signed in) I want to display a message that says 'Please log in to join Group'. Second, if the user is signed in but they did not create the group, I want to display a button for them to 'Join' the group. Third, if the user is signed in, did not create the group, and are already a member of the group, I want to display a 'Leave' button. Last, if the user is signed in and they are the group owner (creator) I want to display the Edit and Delete buttons.
I can determine the first condition by using the props of the component since I'm passing the user object to Group. I can also determine the fourth condition by accessing the user_id of the group itself. Remember, the user_id is the id of the user that created the group and cannot be changed. The tricky part is going to be the second and third conditions relating to the memberships.
In order to determine the second and third conditions I can use the API response, and more specifically, the memberships array in the response. As a reminder, when I load the Group component the response data includes the memberships array. This array is available in the response because I included the relationship has_many :memberships in the group serializer on the back end as well as the :id, :user_id, and :group_id in the membership serializer. Since I have access to all this data I just have to figure out how to use it.
I start by adding the isMember property to the state of the component. The isMember property is false by default. If the isMember proper is true, that means that the current user is already a member of the current group. In order to update this property, I'll need to update my componentDidMount() method. I add a condition to componentDidMount() to determine if there is a user. If there is a user, then I need to potentially update isMember. If there is no current user (not signed in) then I want to leave isMember false.
If there is a user, then I need to determine if the current user's id exists in any of the objects in the response data's memberships array. I use the javascript array method .some() to iterate over the memberships array and determine if any of the objects contain a user_id that matches the current user id. I used .some() because it return a boolean value. I thought about using .find() but .find() return the object itself, which is not what I want.

I don't feel great about this code since I'm repeating the entire axios call with only one difference, but it works for now. I'll come back and re-factor this once I've got the rest of the component up and running.
Now that I've figured out how to determine the membership status in the state of the component, I need to reflect this in the actual rendering of the component. To accommodate these new conditions I create a new variable called buttonGroup which will display the appropriate buttons depending on the conditions of the current user. Each condition will pass a specific button or fragment to the render function.

Now that Ive determined if the current user is a member of the group, I want to set up the handleJoin() method. If the user is not already a member, I want the Join button to create a new membership. Since the 'create' method for memberships uses the current_user object on the backend, I only need to pass the group_id and the token in the axios call. If the action is success, then I want to update state.isMember to true.

By updating isMember to true, the Join button becomes a Leave button on the screen. Now it's time to write the handleLeave() method. This method is similar to handleJoin(), but opposite in a way. To delete a membership, all I need to send is the membership id and token. It takes me a bit to figure out how to access the membership id, but I realize that I can use the memberships array again, and this time the .find() array method. I use the variable memId for the membership id, and now I can successfully leave a group (delete the membership) when the Leave button is clicked.

Now I can successfully join or leave a group by creating or deleting a membership! One bug that I've noticed is that, if I do join a group, the Leave button show us, but clicking the Leave button gives me an error. This is because the new membership isn't found in the memberships array, since the component itself doesn't update. In order to the Leave button to work, I have to back to the Groups list, and then back into the specific group. I'm not completely sure how I'll fix this, so I leave a note and put it on the back burner for now. I'll work on a fix once I'm ready to re-factor the code later on.
The last feature I want to add to the Group component is an indicator to show how many members have joined the group. Using the memberships array once again, I can simply use the javascript array.length property to access this in real time! Now, anyone viewing a group can see how many members it has, just like on Meetup.com!
One other feature I want to add is in the Groups list component. I want to add the same indicator that shows the number of members currently in each group, so I use the same memberships.length property here, and now each group listing shows the current number of members! Happy with what I've accomplished, and with lots more to do, I call it a day.
Below are the four new Group views, as well as the update Groups list component. First, when no user is signed in. Second, when a user is signed in, but not currently a member. Third, when a user is signed in and also a member of the current group. Fourth, when the current user is the owner of the group. Finally, the Groups list showing how many members are in each group!














Comments