Pre-calculating vaccine ingredients: from PostgreSQL to HTML data-*

The VIC pre-calculates ingredient amounts in order to dramatically speed-up performance.  This article describes how its done and why AJAX would be the absolute worst way of doing dynamic calculations on a complex set of variables.

The VIC delivers a tiny database to the browser inside the Ingredient Report page. The data is stored as HTML data-* and the engine is Javascript. “By adding data-* attributes, even ordinary HTML elements can become rather complex and powerful program-objects.” [1]

Once the Ingredient Report is loaded…

…calculations remain instantaneous regardless of the Internet connection quality.  This is important because a busy mom can bring up the report on her phone, tablet or laptop, take it into the doctor’s office and continue to play around with vaccine selections even if there is no Internet connection. Moreover, it just doesn’t make sense to run a bunch of calculations on the server every time a checkbox is clicked.

One thing I’ve found when talking with many developers is that they confuse the value of AJAX with dynamic content (good) versus AJAX for dynamic complex calculations (bad).

Lets take a look at the database for DTaP and multiple data transformations it took to produce it.  If you can use your browser’s dev tools, you can follow along:

Click this link to go to the VIC (DTaP will already be selected for you).

In the console, enter:


#vax-2 is the id of the DTaP checkbox, in which all the ingredient data for DTaP is stored.


Here’s a better view of the ingredient data:

The ingredient data comes from the vaccine_type_ingredient_ranges table:

Lets take a look at what id 817 is telling us: ingredient id 11 (aluminum), is found in 2 of 2 total DTaP vaccines with a minimum amount of 330 mcg of aluminum and a maximum of 625 mcg – depending upon the brand of vaccine given.  The exposure column shows that some DTaP ingredient amounts are not specified, which we call an “exposure to an unknown amount” of the ingredient.

The vaccine_type_ingredient_ranges data is populated from this query, which must be executed after any change to vaccine ingredient data:

This query saves a great deal of calculation time by pre-calculating min/max ingredient amounts for each type of vaccine.

Examples of vaccine types are DTaP, Flu, or HepB.  Within the vaccine type are multiple brands: for example, DTaP brands are Daptacel and Infanrix. Each brand has a set of ingredients that are never the same as other brands of the same type of vaccine – differing in ingredients and ingredient amounts.  The purpose of the vaccine_type_ingredient_ranges table is to generate a list of ingredients common to the vaccine type.  A future version of the VIC will help users to reduce/remove undesired ingredients via brand selection.  For example, aluminum from DTaP can be cut by 50% simply by choosing Daptacel instead of Infanrix.

This code loads data-ingredients, data-ingredient-ids and data-ingredient-amounts, which are analogous to database tables:

the data-* helper methods look pretty simple…

… but hides some complexity.  The ingredient_list (above) is produced for each VaccineType by looping through each of the type’s vaccines (each type of vaccine, such as HepB, has one more more different brands, each of which has different ingredients/amounts).  The code below produces a Set of unique ingredients across brands.


For DTaP vaccine type, which includes 2 brands, the code above produces:

data-ingredients="["Glutaraldehyde","2-Phenoxyethanol","Aluminum","Formaldehyde","Ammonium Sulfate","Bovine casein (milk proteins)","Polysorbate-80"]"

The above ingredient set is for the vaccine type, not any individual brand of DTaP.  This is done because busy parents rarely have time or are willing to call the doctors office to ask what brand of DTaP they offer.  Eventually, more parents will make the request when they see how much different brands differ in ingredients and amounts:

Ingredient Infanrix Daptacel
Aluminum 625.0 mcg 330 mcg
Ammonium Sulfate 1 exposure
Bovine, Casamino Acid (milk proteins) 1 exposure
Bovine casein (milk proteins) 18.3 ng
Bovine extract 1.0 exposure
2-Phenoxyethanol 3,300 mcg
Formaldehyde 100.0 mcg 5 mcg
Glutaraldehyde 1.0 exposure 50 ng
Polysorbate-80 100.0 mcg

The VIC manages a great deal of complexity, hiding it from the user and making it very easy to calculate ingredient amounts.  Without the VIC, just about everybody goes into the doctors office blind, having no idea what or how much is being injected.  The cumulative values from multiple vaccines can be disturbing to see.

Part 2 of this article will explore where the real calc magic happens for the user: when she selects a vaccine by simply clicking the checkbox and javascript performs rapid calculations on the pre-calculated data.  (Sign up for our mailing list or contact me directly to be notified when that new article comes out.)

[1] data-** Accessed on January 21, 2017


Chris Downey

Founder, VaxCalc Labs and creator of Autovist and the Vaccine Ingredients Calculator.

Latest posts by Chris Downey (see all)

Author: Chris Downey

Founder, VaxCalc Labs and creator of Autovist and the Vaccine Ingredients Calculator.

Leave a Reply