FuelUp

FuelUp is a React-based application that allows users to search and navigate to gas stations with the cheapest gas. Features include locating the user's coordinates upon load through the HTML5 Geolocation API to find accurate stations in the area, displaying the gas price markers according to station location on Mapbox, filtering station results by fuel type and brand and updating the map accordingly, and saving favorite stations through an optional account creation with user authentication and password encryption via Passport.js and BcryptJS.

Problem

When it comes to other gas price search applications, the user would need to go through a series of clicks in order to get the information for all fuel types, visualize the results on a map, and navigate to the station. It would be much more advantageous to have an application that does the following:

  • Display the results in both list and map format on one page, including station name, location, and prices for all fuel types.
  • Dynamically update the page through filtering stations by fuel type, brand, or, if the user has an account, location.
  • Open up a new window or application to Google Maps when the user chooses to get directions to a station.
  • Add and remove stations from favorites and visualize all favorites if the user has an account.

Development Process

The structure of the application was designed so that users have access to the most important features at the very beginning instead of creating an account just to test out the functionalities. Here's the breakdown for FuelUp's general development:

  • Finding a source. GasBuddy is the most reliable source that offered real-time fuel prices, however it comes with its own limitations. GasBuddy itself is not 100% accurate- the fuel prices presented is supplied through crowdsourcing means. Along with that, there is a lack of API for the information. Seeing that this was the closest I could get to retrieving accurate and up-to-date results, I opted to scrape all of the general gas station information from the site.
  • Getting the user's current position. The HTML5 Geolocation API retrieves the user's longitude and latitude coordinates if the user allows the browser to receive their location. The coordinates are sent to the Mapbox Geocoding API to be converted into a zipcode, and then passed as a endpoint for Axios. Otherwise, Austin's zipcode, 78753, will be used as a parameter for the call instead.
  • Scraping from GasBuddy. The endpoint is provided by the geolocator or the default city upon load or through search submission afterwards. The GET request was set up through Axios to GasBuddy on the server-side instead of the client-side due to CORS issues. The page was then loaded into Cheerio where the information becomes targetable through jQuery functions. GasBuddy doesn't display the prices for all fuel prices for the results on the same page, so multiple asynchronous Axios calls was made to retrieve all the prices from different pages. The station information was placed in an object array and sent back to the client-side.
  • Converting the location. The results were mapped through in order to find the station address. The station address is sent to the Mapbox Geocoding API to be converted into longitude and latitude coordinates. The coordinates are then used to determine the position of the markers on the map.
  • Filtering the results. The filters applied were through conditionals determined by the text of the dropdown. As the filters are applied, the results are sorted by the lowest price of the category and the prices on the map updates depending on the fuel type selected. The filters are reset back to their default placeholder once the user submits a new search.

In addition to FuelUp's search and navigation features, creating an account also allows users to add stations from the homepage into their favorites. They also have access to a new page listing all of their saved favorites in a similar format to the homepage.

  • Creating an account. User authentication is set up through Passport.js and the user information is stored in the MongoDB database. Before the account is saved in the database, the password submitted is hashed through BcryptJS. Emails are unique, so the same email cannot be stored in the database.
  • Saving to favorites. Once the user has either created an account or logged in, they can favorite their stations displayed on the homepage. They can also see the stations they have saved previously to prevent double submission. If a station is saved, a POST request is sent to store the station information in the Station table. Afterwards, a findOneAndUpdate() method is called and the station id is inserted through $push. Since the address to the stations are unique, if it matches the address from the saved stations, the heart next to the station name will be filled.
  • Removing from favorites. The id of the favorited station is sent as a prop through the components. If the user reselects a filled heart, a DELETE request will be sent to remove the station from the database by id. As a result, the filled heart will turn back to an outline.