This is a log of stuff I did w/ one of my random pet projects, it’s not terribly interesting and is mostly just so I can get into the habit of writing more. You have been warned.
This last session I decided to work on integrating mealplanner with Instacart and was even able to finish it despite making the extremely poor personal decision of purchasing Elden Ring (which I definitely want to write about eventually).
First, before coding, I looked at different possibilities for the integration. The first thought any dev would have is “Is there an API?”. Turns out there is one, but it’s not open and you can only get access by requesting it. I assume their primary users are going to be other companies and not unfinished open source apps like this one. And even if I did get access, use of their API did not seem as fluid and simple as, for example, GitHub’s REST API. And it also didn’t seem to provide all the information I needed, just a way for department stores to process orders through Instacart. It was not an workable direction for me.
The only other possibility I could find was a feature Instacart seems to have developed for content creators that
create content tangentially relevant to the act of shopping for groceries, ie, recipes. People who create recipe
blogs, for example, or websites with large recipe databases, can send the recipe ingredient list to Instacart via
a simple URL: https://www.instacart.com/store/partner_recipe?...
with the ingredients listed in the query parameters.
This isn’t an ideal solution either since I wouldn’t be able to pick specific products; there’s no way for me to know what’s in stock at a store, or even which stores are available without access to the API. Users would have to do the work of picking specific products, and picking the right quantity themselves.
Unfortunately, there wasn’t a better solution I could find, and this one, while not ideal, is workable, so it’s the one I went with.
Once I realized this I did some more research and found I could send a default zipcode and store (via an Instacart defined retailer ID), as well
as default ingredient quantities via query parameters in the partner_recipe
URL (that last one was literally just a lucky
guess while playing with the URL).
Before starting on it though, I needed another small feature implemented: application settings.
Settings
I’m now at the start of most of the features that will require user settings, defaults users need to specify. For the Instacart integration, there’s the zip code people will order delivers to and the default store to order from.
I didn’t want to create a hardcoded Vue component with inputs for this, so I created a generic settings page that features could non-intrusively add to. Settings are defined like this:
export const DELIVERY_ZIPCODE_SETTING = 'delivery_zipcode';
SettingMetadataStore.registerSetting({
name: DELIVERY_ZIPCODE_SETTING,
title: 'Zipcode',
group: 'Delivery',
order: 0,
description: 'If you plan on getting your groceries through a delivery service, set your zipcode so '
+ 'mealplanner can let the delivery service know.',
component: defineComponent({
props: {
modelValue: null,
name: {
type: String,
required: true,
},
},
emits: ['update:modelValue'],
render() {
return h(SimpleSetting, {
type: 'text',
modelValue: this.modelValue,
name: this.name,
placeholder: 'Enter your zipcode',
'onUpdate:modelValue': (...args: unknown[]) => {
this.$emit('update:modelValue', ...args);
},
});
},
}),
});
The settings page uses the SettingsMetadataStore
and another store for the setting values themselves (stored in an SQLite table)
to display the settings like so:
It looks a bit ugly at the moment. I wasn’t sure how best to style it, so I’ll need to look around at some other examples I think.
The ‘Order on Instacart’ button
With the ability to define settings implemented, adding the integration w/ Instacart was next, and was a relatively
simple thing to code. I added a button to the grocery list that opens the partner_recipe
link in a browser window:
All it really needed to do was build the correct instacart.com URL.
Reviewing the entire workflow
Now that the entire workflow of picking meals and ordering ingredients was implemented, I decided to try it out and review the process from a usability standpoint. I was able to create the mealplan I wanted and get a grocery list on Instacart relatively simply. It took maybe ~30 mins at most (unfortunately I did not time myself) and didn’t feel like a lot of work. Which is great!
But I also noticed a lot that could be improved on in this early version:
-
First and most evident was that having days of the week in the mealplan or days at all was completely useless. Scheduling meals for days is just not a useful or normal thing to do. AFAIK people (like myself) generally pick things that they will want to eat in the next X days and then pick the specific meal to make near the time of cooking itself. There’s absolutely no need to assign meals to days before even having the necessary ingredients.
So I’m going to remove days entirely from the UI, and instead just have a list of meals. This’ll make the process of using the app much simpler and declutter the UI a bit. It also means that a lot of the drag-drop code I implemented no longer needs to be there, so I did that for nothing I guess :/.
-
I also noticed that a lot of the plated recipes have wildly varying ingredients, which can really add some bulk to your shopping list. I found myself adding multiple instances of the same recipe to a mealplan and want to make this action a lot easier. I will probably add +/- icons next to meals in the new meal plan display.
-
Looking at the recipe details themselves I noticed it was extremely hard to quickly see in a recipe how an ingredient is used. The recipe cards that Plated itself used bolded ingredient names in the recipe step text, which seems like an idea worth replicating here.
-
And I noticed that, currently, there’s no way to save a mealplan. @hich means after ordering it would be really easy to just not remember which recipes you selected :). So I need to make the mealplan persist. There will be one mealplan total with some kind of “I cooked this” button to remove it. Though I’m not sure when this view would be visible since it shouldn’t be there when building the mealplan…
-
Some ingredients in plated recipes are not recognized by Instacart. They exist, but Plated wanted to be the fancy mealplan kit, so it would list ingredients like “haricot vert” instead of “french green beans”. Some kind of hardcoded list would be useful to keep users from doing unnecessary work.
-
Right now there is a whole, simple workflow for creating a mealplan: pick recipes, check which ingredients you already have, then order the rest. But users don’t actually have a way of knowing that. There are no instructions or help docs. So that seems like a worthy thing to add. Specifically as some kind of wizard that, non-intrusively, guides you in using the app.
-
And finally, I definitely need to add a toast mechanism to show short messages like “Grocery list copied!”. And it would be nice to have some really fast appearing tooltips to show people how to use specific parts of the UI.
Anyway, that’s all for now. Next time I will be implementing parts of my review above and hopefully starting on nutritional analysis, which I’ve already done some research for.