Build a full stack application that does the following:
Write an API endpoint that returns a filtered set of users from the csv provided below.
- Your API endpoint URL is /users
- Your API responds in the above format with valid GeoJSON
- Your API should correctly filter any combination of API parameters
- Your API should utilize a database
- Your API should support paginating the number of resulting users
- This should be built using Express or Flask
- Your API should be tested
Parameter | Description |
---|---|
fav_color | Your favorite color |
dist | Maximum match distance in miles |
origin | lat/long string of your location |
min_age | Minimum age preference |
max_age | Maximum age preference |
Given the following request:
GET /users?fav_color=red&dist=100&origin=37.774929,-122.419416&min_age=21&max_age=29
The expected response should contain the following:
{
"metadata": {
"path": "/users",
"query": {
"fav_color": "red",
"dist": 100,
"origin": "37.774929,-122.419416",
"min_age": 21,
"max_age": 29
}
},
"num_results": 1,
"results": [
{
"type": "user",
"locationHistory": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"city": "Oakland"
},
"geometry": {
"type": "Point",
"coordinates": [-122.2711, 37.8044]
}
},
{
"type": "Feature",
"properties": {
"city": "San Francisco"
},
"geometry": {
"type": "Point",
"coordinates": [-122.419416, 37.774929]
}
}
]
},
"properties": {
"id": 1,
"name": "Taylor Swift",
"age": 27,
"fav_color": "red"
}
}
]
}
All query parameters are optional. If a query parameter is missing or the value is invalid, you should skip the related filter.
All minimum and maximum fields should be inclusive (e.g. min_age=21&max_age=23 should return users with an age of 21, 22, or 23).
Your application should have a frontend that displays a form and allows a user to input a favorite color, distance, origin and min and max age. When the form is submitted, a map should render with markers for the location of the users found. You can use Mapbox, Leaflet or any provider for this functionality.
To clone and run this application, you'll need Git and Node.js (which comes with npm) installed on your computer. From your command line:
# Clone this repository & the companion backend repo
$ git clone https://jdegand.github.io/rithm-coding-challenge
# Install dependencies
$ npm install
# need to import csv file into mongo database - can input data manually or use mongoimport - check data shape in leaflet.ejs
mongoimport --uri mongodb+srv://<USERNAME>:<PASSWORD>@cluster.mongodb.net/<DATABASE> --collection <NAME> --type csv/json --file <FILENAME>
# Add MONGO_URI variable in an .env file
$ npm start
# To test app, you need to run npm start and then in another terminal - npm run test
- For mongodb geojson, longitude needs to be listed before latitude but leaflet needs latitude before longitude.
- The shortening of longitude and latitude in the csv causes problems if you want to use a csv converter website. Need to edit the file on github and give them full names before pasting the data in the converter.
- The ages of all the celebs are wrong in the csv and not just because they are out-of-date - they were wrong initially.
- Installing mongoimport is convoluted. It is much quicker to manually add the data directly to atlas.
- I converted the data to geojson with a converter and then input the data one object at a time using the insert button.
- Client.connect's use of callbacks is deprecated - need to refactor or use 'mongodb-legacy' package.
- I resisted using mongoose here - it makes it easier to connect to mongo but no other real use in this application.
- Documentation on using express without mongoose is surprisingly sparse and mostly out-of-date.
- Need to look into having a variable zoom level on a leaflet map.
- (0,0) location is all blue ocean and you can be fooled thinking the map didn't load in correctly. It would better to have a more zoomed out view for that case.
- $gt / $lt is not inclusive - need $gte / $lte
- meters to miles - divide by 1609
- miles to meters - multiply by 1609
- Had many failures on getting the right formula to test this app
- A Mocha and Chai implementation similar to the RedditJS tests did not translate to this app.
- Mocha and Chai (in particular) seems to be an outdated way of testing.
- Mixing promises and callbacks seems to cause problems with chai.
- Had to search on github to find something that would work when testing the application
- Tests are similar to this
- Instead of using cheerio, could have used a jquery plugin
- I am sure there are better ways to test this but I don't want to devote a ton of time to this
- If I had used react, I would have used cypress
- Convert CSV
- Mongo - mongo connect to your database
- Mongo - mongoimport guide
- Mongo - mongoimport
- YouTube - import csv into mongo using node
- YouTube - export json into mongo atlas
- Stack Overflow - import data into mongo atlas
- Isotropic - pagination in mongo
- Stack Overflow - ignore a parameter in a query if it is null
- YouTube - 56. What is GeoJson Data. Adding Geo Spatial Data to store the places in the document - MongoDB
- Stack Overflow - connect to mongo without mongoose
- Stack Overflow - express and mongo without mongoose
- Rithm School - api tests with jest
- Stack Overflow - bad authentication atlas
- Github - sans mongoose
- Dev.to - mongo without mongoose
- Github - mongo without mongoose
- Github - mongo node quickstart
- Mongo - mongo crud tutorial
- DZone - crud operations on mongo
- Stack Overflow - get mongo collection by name in node
- Mongo - express mongo rest api tutorial
- Github - mern stack example mongo
- Stack Overflow - optional parameters for mongo query
- Leaflet - leaflet quick start
- LaraCasts - leaflet not showing fully on page load
- Stack Overflow - access ejs variable in js logic
- YouTube - 16 MongoDB Queries - Fields Filtering
- Stack Overflow - optional parameters in mongo query
- Stack Overflow - calculate distance between 2 points in leaflet
- Stack Overflow - multiple markers in leaflet
- Stack Overflow - access passed ejs variable
- Stack Overflow - split long array to smaller arrays
- Stack Overflow - map an array by every 2 elements
- Stack Overflow - loop through json in ejs
- Stack Overflow - leaflet lat undefined error
- Leaflet - instead of using setView()
- Stack Overflow - set view for an array of address coordinates in leaflet
- DelftStack - mongo find with multiple conditions
- Raddy.dev - mongo query with custom url parameters
- Stack Overflow - promise chain
- Stack Overflow - drawing circle with radius
- GitLab - mocha chai
- Stack Overflow - mocha & timeouts
- Semaphore - node & mocha
- Stack Overflow - mocha async is timing out
- YouTube - API testing with chai http and mocha - JSON testing in JavaScript and NodeJS
- Stack Overflow - test rendering views with ejs in mocha
- Github - unit testing nodejs route
- Github - used same method to test application
- Stack Overflow - cheerio get js variable