“Simple” Solutions in Theory Are The Hardest to Implement

It took about 12 days (Ok, I procrastinated posting this on Stack Overflow for a couple days, and didn’t think about this at all over the weekend, but still…) for me to implement this amazing, mind-blowing feature you see below:

“Well, what was that?” You may ask.

’Twas a form with checkboxes on an “Edit Listing” page where the boxes would populate with an option that was already chosen before, and would also support the addition or subtraction of extra positions.

The process went something like this:

  • V-model doesn’t work here, what gives??
  • Post on Stack Overflow
  • What the heck am I looking at with this guy’s answer??
  • Oh cool, I overthought the automatically checked feature!
  • It Works! I’m Done!
  • Wait…
  • This array of selected positions isn’t updating
  • Gets confused by Stack Overflow again
  • Googling array manipulation functions used in the answer
  • More googling
  • Understanding 50% of the final step that I need, and form a half-baked solution which in turn doesn’t work
  • More googling
  • Finally it works for real!

The link to the Stack Overflow is here: https://stackoverflow.com/questions/67469837/vue-loop-array-objects-into-form-checkbox/67476731?noredirect=1#comment119276326_67476731

The working solution was written in vanilla Vue, while I’ve been working with Nuxt since I started, so I ended up touching up on what Functional Components were first.

Next, I did my best to understand the flow of data from component to component, and got a basic grasp of each component did.

  • The bottom-most looped through the returned array of objects from my API endpoint and provided Crew Positions after array.split was applied to it up to component above it.
  • The middle component took in Crew Positions and provided a :checked prop to the top-most component, and contained a method that contained the logic needed to dynamically update data back on the bottom component. (I didn’t understand ‘toggleCrew’ at first)
  • The top component was mainly to display the checkboxes, and had an event listener that would eventually make its way down to update Crew Positions based on what boxes were checked.

Working in Nuxt, I have a separate folder for Components, and having nested components didn’t seem like good practice, so I went about trying to combine all this functionality into one parent and one child component

First, I created a hard coded array containing all the possible Crew Positions and looped through it all. Whichever position was included in the data from the API also, made it into the :checked prop.

At this point, I was like “Oh Yay, I’m done!”. After all, my question was for how to get those boxes to be checked, I figured the updating after the fact would sort itself out. Until it didn’t, that is.

The most sensible thing to do at this point seemed to be to understand everything that I wasn’t sure of, since the answer probably lay there.

After a touchup on

  • Ternary operators
  • Array.filter
  • Array.split
  • Array.map

I had a much clearer idea of how this logic worked:

Positions would either be an array without ‘crew’ (the checkbox selected value) since it was unselected, or an array with the old Crew Positions with ‘crew’ added to the end.

returnedListings would consist of objects with Crew_Positions in array form instead of a comma separated string. This step was crucial for two-way prop binding to occur.

At this point, my understanding of the ‘.sync’ event was still a bit hazy so I my attempt at updating Crew_Positions ran into an issue with for loops.

Each ‘position’ here would be fed into the Component’s template where there would only be one checkbox instance.

My plan here was to store ‘crewPosition’ into an empty array and emit that to the parent where it would be added to the Crew_Positions array. The issue was that on each click, the emitted array would reset and there was no way to keep a running total of what was chosen.

Once I read over .sync once again, it all clicked. I was confused originally by the answer on Stack Overflow since it followed prop naming that included both CamelCase and kebab-case, and the concept of two way binding in general.