For my first round of polishing changes, I returned to the recipe page, where things were sort of working, but in definite need of love. I hit several different areas, and the page is pretty close to where I want for first release (alpha?) now. Let’s walk through the changes real quick.
New Algorithms for Line Parsing
Previously, the code for moving from how the backend understood line/ingredient associations (start-end tokens), to how the frontend understood line/ingredient associations (individually labelled words), was a bit convoluted and difficult to follow. Part of this is due to the complexity of the problem, but I thought that I could make it a bit simpler and easier to follow, which would help as I attempted to fix some of the bugs that were still in the system.
The first function I changed was mapTextToIngredients
, which converted the backend-provided ingredients and tokens to a form the frontend can use. Previously, I had iterated through the array of words a single time, checking if each index was on or between a relevant token.
Now, however, I iterated twice, once through the ingredient list, and once through the word array. The first iteration places down the start, end, and single tokens. The second iteration fills in the gaps between them.
I like this more because the code is cleaner and easier to understand, since there are less nested if
statements.
Next, I modified the even larger setNewIngredientTokens
function, which determines the new layout of the line after an ingredient button is clicked. Most of my work here was in splitting the function into smaller functions, to improve readability of the code. I also switched my cumbersome fetch
call to my new axios object.
I also tried to limit some of my Java-style for
loops in favor of .map()
and filter()
, which I felt were cleaner and easier to read in general. I didn’t get rid of all of them, but I still think it’s quite an improvement.
You may also notice that I’ve begun reverencing an attribute called color_index
that is part of the RecipeLine
retrieved from the backend. This is part of my latest changes to the backend, which now supports persistent colors, rather than dynamically coloring based on location in the line.
Backend Changes
Recall that, previously, the color of a line was determined by the ingredient’s place in the line: the first ingredient was always colored teal, the second was colored orange, and so forth. If an ingredient was defined before an already-existing ingredient in the same line, then the first ingredient would become the teal ingredient, and the already-existing ingredient’s color would change to reflect that.
I didn’t like this; it seemed unprofessional and confusing. I wanted each ingredient/line association to be paired with a specific color that wouldn’t change.
And it turns out, I already have a structure for line/ingredient associations.
This is just a simple integer variable that references the array of colors in the frontend. This way, the backend doesn’t need to know the exact color (making it much easier to change), and the frontend can easily understand what is expected of it. But it wasn’t enough to simply define this additional value; I needed places where it would change according to both user input and automatic detection.
I started with the latter, because it was a pretty easy fix.
When using the spaCy library to parse a new ingredient, there’s no user input on the colors, so I just kept the initial order in the line. Each time an ingredient is found, the color_index
variable is incremented, ensuring that each ingredient on the line has a different value.
I then made some changes to the function that parsed the frontend data for new ingredient associations. I also did a bit of refactoring work to make it more readable.
There’s at least one more thing I’d like to do here: the ingredient_list.append()
call happens more or less identically in three different places and takes up four lines per place. Creating a small function to do this work would probably make the code a bit more legible. It’s something I would like to go back to in my final pass, but honestly at this point I’m just completely sick of this part of the project. The recipe and ingredient line associations are swimming around in my head and sometimes it feels like I can’t make heads or tails of them at all anymore.
Editing Titles of Lists and Recipes
In between my work on the above, I took care of a quick issue which has been bugging me for a while: the inability to alter the names of recipes and lists.
I solved this by creating a quick, reusable component that made use of the TopSquiggle
and BackButton
components, and combined them with a new call to the api. This prevented passing of unnecessary props between the components and made them more reusable. I added a type
prop to map onto the url of the api call to make the component more reusable.
This component works very similar to its predecessor in my first version of this project; it sends a call when focus leaves the object or when the “Enter” key is pressed. I wanted to make manipulations as easy as possible, and I’m pleased to report that this part was created without a hitch.
Next Steps
Still plenty more to do, unfortunately. I want to revamp the Grocery List page and alter the styles around in order to give the first release a more polished look. I also need to create a title and explanation page for how the site works, and write up better documentation (or even just documentation at all). I would also like to look into some simple animations, although that’s something I would pretty much need to learn from scratch.
But hey, I’ve learned everything else here from scratch; what’s one more?