CallCongress.How (Version 2)

CallCongress sreenshot

What is CallCongress.How?

This is a rebuild of my previous CallCongress project with a more robust API and a better database system.

Technical Discussion

The front end of this app was bootstrapped with create-react-app.
Node.JS (by way of Express)
The app is running on an Express server for its internal API and route handding.
User data is stored in a PostgreSQL database.
Additional Libraries
This app makes use of Axios, Passport, React Router, and Express-Sessions.
Rather than using an external CSS framework, I made use of CSS's built-in flexbox property to create a lightweight and responsive site.
ProPublica API
I used the ProPublica Congress API to get the information about legislators and laws.

Notes on App Structure

CallCongress.How is neatly divided between two sections: the React frontend and the Express backend, connected through AJAX calls. Here’s an example of one such cycle from the Bills component:

// in the Bill component, when the component mounts,
// the component sends a request to the server's backend.
  componentDidMount() {
      .then((res) => {
      .catch((err) => console.log(err));
// then, the api/ext router catches the request.
extRouter.get('/bills', lawHelpers.getHouse, lawHelpers.getSenate, lawHelpers.manipulateBills, (req, res, next) => {
    message: 'ok',
    houseInfo: res.locals.houseInfo,
    senateInfo: res.locals.senateInfo
// after the two requests to get the information, the responses
// are manipulated into a form the component can use:
function createSortedLawSet(arr) {
  let newLawSet = [];
  for (let lawSet of arr) {
    lawSet.forEach((law) => {
      law.lookup_cc = law.number.split(/[\s\.]{1}/g).join('').toLowerCase();
  newLawSet.sort((a, b) => {
    let timeA = manipulateTime(a);
    let timeB = manipulateTime(b);
    return timeB - timeA;
  return newLawSet;

function manipulateTime(obj) {
  let time = new Date(obj.latest_major_action_date).getTime();
  return time;

function manipulateBills(req, res, next) {
  res.locals.senateInfo = createSortedLawSet(res.locals.senateTemp);
  res.locals.houseInfo = createSortedLawSet(res.locals.houseTemp);
  return next();
// which is sent back as a JSON response.
<!-- Finally, the information is sent back to the component,
 where it renders in the appropriate subcomponent. -->
<div className='bills-list'>
  {( == 'senate') ? 
  <BillList laws={this.state.senateInfo} 
    learnLaw={this.props.learnLaw} /> : 
  <BillList laws={this.state.houseInfo} 
    learnLaw={this.props.learnLaw} /> }

The Making of CallCongress.How

J Silverstein
Event icons are from a number of people on TheNounProject: Ana María Lora Macias, iconsphere, Lorena Salagre, Sherrinford, Juan Pablo Bravo, and Wilson Joseph.
Most of the inspirational quotes on the home page are from the West Wing.
Thanks to my wonderful instructors and peers at General Assembly for making this experience extremely meaningful.

Opportunities for Future Growth

I have a pretty solid plan for the next stages of

Next Steps

In addition to the next few levels, I plan to refactor some portions of the app as it currently exists.

Future Stages of Development has been a project of mine for some time. Initially envisioned as a static site serving up phone scripts to make calling congresspeople easier for those who may not be at their most eloquent on the phone, it’s evolved in my mind into something more interactive. I don’t think it’ll ever be a full-blown social network, exactly, but it’s evolved into a tool that can be used to build political momentum, keep voters informed about their legislators’ activity, and bring like-minded people together.

That being said, a resource of user-submitted phone scripts for political action would still be valuable, and I’d like to add in a way for users to add scripts and tag them with the appropriate bills, topics, people, or locations. This would also require a way to moderate the submitted scripts.

Beyond that, it would be challenging but exciting to add local government officials to the mix. State and local governmental APIs are hard to find, and the ones I have found are frequently abandoned (for example, the Indiana API hasn’t been updated since 2014). However, change doesn’t start at the top – it starts at the bottom, with grassroots movements of well-informed citizens who work together to make a difference in their towns, counties, districts, and states.

In the far future, my vision for includes a national network of people working to provide information on local politics in real-time.