Want To Find The Best Schools Or Safest Cities in America ? CitySpire Does It All

It all started two months ago. I had just completed the Computer Science portion of my coding bootcamp and was to begin the final unit in my Full Stack Web Developer Program. The final portion of the school’s curriculum is an internal apprenticeship program called, “labs”. Labs consists of multiple cross-functional teams where team members collaborate with one another to build an awesome web application. Teams consists of web developers (frontend and backend), data science specialists, and iOS Developers. As time to begin labs approached, we waited anxiously to find out which project we would be assigned, and who our team members would be. Finally, the moment arrived as we were assigned to our labs project channel on the Slack Platform. I was assigned to the CitySpire Application. My team consisted of ten members: five web developers, four data science members, and a team lead.

The CitySpire Application is a web application that provides useful information about a searched city. Previously, if a user wanted to get city information, they would have to navigate multiple websites to gather all the relevant city information. Our application would solve this problem. We would build an application that would provide all information a user would want from a city search. In order to accomplish this task, our team incorporated user stories into our project to determine which features and information a user would like from a search of a city. A couple of these user stories we incorporated into our project, included a person looking to move his family to a city with a lower cost of living and good schools. Another user story is a person moving to a new city to start a new job. This person is trying to find relevant information about her new city. We set out to put ourselves in the user’s shoes in building out our application. Our main goal for the CitySpire Application was to be the one stop shop for all users searching information about a city.

As a web developer, my main concern going into the project was how all the pieces of the application (frontend, backend, data science) would come together. None of the web developers on our team had any experience working with data science in the past so this was the first time for all of us. Furthermore, I didn’t fully understand what data science did. I knew that the frontend application would pull city data from the API’s the data science team would set up for us, but that’s all I understood. Scrubbing API’s ? Huh, what does that even mean ? As time went on and we worked on our individual components of the application, the picture became more clear. We knew when it was time to collaborate and consolidate our individual pieces to form a robust, functioning web application. Effective communication in standups, Zoom Meetings, Slack Notifications, and Trello Board updates were the key to team success.

Snapshot of our Trello Board:

CitySpire Website: https://f.cityspire.dev/

Snapshots of the CitySpire Application landing page:

Ah, The Technical Stuff

Our team took over the application from a previous labs team, which had begun the original CitySpire Project. The former labs team had left the application somewhat incomplete. The landing page was not aesthetically pleasing, some of the functionality on the “pinned cities” page for example, was not working. Additionally, the previous CitySpire Application required a login to access any part of the application. As a team, we wanted to make the application pleasing to the eyes and present an easy, intuitive interface to the user. Additionally, we wanted to open up the application so that any user could get city information without login. We would require login for using functions such as “pinning” cities, which would be saved to the user’s profile. Furthermore, we added a user dashboard which provided information about a city’s population, school ranking/score, unemployment rate, average rental price, sunny days per year, city safety ranking, and city danger ranking. Each of these categories is displayed on the landing page. By clicking on the “view” button for Best Schools for example, and selecting a city, the city information will be displayed on the dashboard and a list of “recommended” or similar cities based on the search will be provided at the bottom of the page. Clicking on any of the recommended cities will display that city’s information. The user can “pin” a city to their profile for later viewing on the pinned cities page. On that page, the user has the ability to remove a city from pinned cities and can view the city information by clicking the “view city info” button.

Going to “Best Schools” category and selecting city
Typing city in search bar and pinning city

As a team, the biggest technical challenge we encountered was that our data science team was not able to provide the frontend web application with city API data. The work around for this problem was that the backend team, which I was a part of had to create seed data for forty-two cities. These forty-two cities are included in the six categories we have listed in the landing page for the CitySpire Web Application. Again, these categories included: a city’s population, school ranking/score, unemployment rate, average rental price, sunny days per year, city safety ranking, and city danger ranking. A sample of our seeded data is included below:

Seed Data for Best Schools

Another issue we came across as a team was in the frontend web application. The pinned cities/remove pinned cities functionality was not working properly. A team member came up with a one-line fix that corrected the problem. It was adding a window refresh to the on-click handler for pinning a city in header.js.


My role on the labs project was the web backend (Node.js) developer. I had one partner working with me on the backend application. As the backend developers, we were responsible for adding a “save city” feature to the application which would allow a user to add/save a city to their user profile. The saved cities could then be viewed on the pinned cities page. I was tasked with creating the API endpoints with which the frontend application could connect and perform the save feature for a city as well as the ability to delete a city from their user profile, and most importantly, retrieve/get all the cities saved to their profile. As part of this task, I also added the corresponding database methods for the PostgreSQL Database. These methods included the ability for a user to save a city to the database based on their user profile, delete a city from the database, and get all the cities saved to their profile from the database. In the process of completing these tasks, I collaborated with my backend partner about the endpoints/database methods that should be created. I also collaborated with the frontend developers to pass them the API endpoints that they required for the frontend user interface.

API endpoints found in weaherRouter.js
Database methods found in weatherModel.js

As I was testing the original API endpoints/database methods in the Postman Application, I discovered an interesting problem. I was getting “binding” errors. I came to the realization that the proper way to add these endpoints would be to place them in the profileRouter.js (router file), where I could add these endpoints to the root URL as “/profile”. This made the most sense to organize the “savedCities” endpoints in this fashion since the cities would be linked to a specific user. Most importantly I was finally able to test the endpoints successfully in Postman without the “binding” errors. So ultimately, the implementation was successful.

The original implementation of the savedCities endpoint:

app.use([‘/profiles/:id/savedCities’, ‘/profile/:id/savedCity’], savedCitiesRouter);

The fix was as follows:

app.use([‘/profile’, ‘/profiles’], profileRouter);

I played a small role in the frontend application. I created the category modals for the cards displayed at the bottom of the landing page. A frontend developer had already created the cards. The modals I created made the API calls to the backend endpoints to retrieve the cities listed in each category. Material UI was used to highlight the cities on hover. Luckily, this implementation was fairly simple and there were no issues.


The Path Forward…

As a team we successfully delivered several features to the CitySpire Application. The frontend application design is much improved from the original CitySpire that we inherited. The TypeIt Animation the frontend developers came up with is beautiful. Furthermore, we created categories at the bottom of the landing page where a user can select a city by category and then view city information on the user dashboard. Additionally, the user can get a list of recommended cities based on that search. Entering a city in the search form also directs the user to the dashboard. The dashboard has been completely rebuilt. On the pinned cities page, the “remove city” and “view city data” features are fully functional. Lastly, we removed the requirement for a user to be registered to use the CitySpire Application.

Dashboard displaying city information
Pinned cities page

Future enhancements to the application would include the developing the Map Box/mapping feature. We were unable to deliver this feature. Most importantly, we need to complete the data science portion of the CitySpire Application. This application would have been so much better had the user been able to enter any city in the search bar and pull the city info directly from the DS API’s. Additionally, the category card modals could be changed to dynamically list cities based on changes in the rankings of their respective categories. Furthermore, both the dashboard and pinned cities pages could be further enhanced to display additional city data. The data science portion of this application is the biggest challenge to overcome by future developers in this project. Unfortunately, we were unable to get this part of the project working. This is the biggest web project I have ever worked on. I hope my organization and planning were much improved during the course of this project. That is something I will continue to improve upon. My labs team were awesome people to work with. I would love the opportunity to work with any of them in the future. This project has laid the foundation for my career in web development. My role on this project has shown that I can work collaboratively with a team remotely to deliver a large project on time. I am proud of the application we delivered.

Full Stack Web Developer