I try to live a Zero Waste lifestyle. In brief, Zero Waste for me is about reducing consumption, in particular plastic products. I relocated to Norway, I realized it takes time to find out where plastic-free products are sold.
For this reason I am implementing this app where users can search and log stores selling Zero Waste or Less Waste products. This app uses Google Maps to search for stores, and will allow you to save them together with their products so that you or other users can look them up.
This is a MEAN app (MongoDB, Express, Angular CLI 7.0.6, Node.js) using the Google Maps API to show store locations on an embedded Google map.
On the back-end a server is based on Node.js/Express server. The Mongoose ODM is used to connect Node.js and the MongoDB database. It provides a schema based solution to organize models and run CRUD operations. JSON web tokens [JWT] handle user authentication and identity management. The front-end is built with Angular-CLI 7, Bootstrap, and Angular Bootstrap. The app uses RxJS for asynchronous or callback-based code.
Through the frontend users can search an address using Google Maps' geolocation. The results are displayed as markers on the Google map.
I implemented a "caching" system that checks whether the searched address is already present in the MongoDB database [DB]. This allows the app to call Google Maps less often, and to load a store/location already present in the DB.
The user has a personal quota for the number of geolocation searches they can run. The quota can be set in three environment variables (see below) as an integer for the maximum number of queries per hour, day, and total maximum. This was done to limit my bill with the Google Maps API.
A form appears when you click on a marker. This form contains user editable information on the store such as the store type, store description, etc. This form allows the user to save or update the store/location to the DB.
To use the Google Map functionality a user is required to register and login. JWT is used to transmit sensitive information (e.g. passwords, access tokens) between front-end and back-end. A password reset functionality is implemented in the back-end using express-nodemailer, handlebars for express and express-nodemailer, and AJAX requests.
NB: This app does not use agm-core for Google Maps as described in many tutorials. IMO at the time of writing the documentation is insufficient to extend the agm-core component and implement functionalities such as InfoWindow or callbacks from markers.
Install node, npm, mongoDB, Angular CLI, and see the standard generated README below. Install the Angular and Node.js dependencies with:
cd backend
npm run client-install
This script uses concurrently to run npm install
on both back- and front-end folders.
For deploying the front end check the Build section below and the Angular deployment documentation
Create a .env file with environment variables for the Node.js back-end. Use a template in .env_example.
cp .env_example .env
vi .env
Similarly to dotenv, set up environment variables for the Angular frontend in the ./environment.ts and ./environment.prod.ts files, which are used for development and production, respectively.
Get a Google Maps API key here to use Google's geolocation service. Place the API key in the ./src/index_INSERTKEY.html file, then rename that file to index.html. This allows you to use it for geocoding from the front end (see src/app/modules/map/map.component.ts).
The code still includes my implementation of geocoding from the server back-end. This implementation uses npm-geocoder but I commented it out in the code. To use it set up a Google Maps API key for using it on a server and see the backend/server.js file.
Launch the MongoDB database:
mongod --dbpath <path to data directory>
Launch the Node.js back-end in the ./backend directory. As an example, use one of these three commands below:
cd backend
npm start //using npm
node server.js //using node
nodemon //using nodemon
Before launching Angular fix the index.html file as explained before:
cp ./src/index_INSERTKEY.html ./src/index.html
Launch Angular for the frontend with one of these two commands:
ng serve
npm run start
Alternatively, use this command to automate the previous two commands on the back- and front-end:
cd backend
npm run dev
Open your browser at http://localhost:4200/. The backend API is by default at http://localhost:4000/, and you can for instance check the http://localhost:4000/ or http://localhost:4000/ endpoints.
In addition to the previous steps compile the Angular app into the /dist folder:
ng build --prod
The /dist folder is served by Node.js when the environment variable NODE_ENV is set to 'production', so do that before launching the backend with e.g.:
NODE_ENV=production node server.js
Here are some references I am using to develop MEAN applications:
MEAN App tutorial with Angular 4
Integrating Google Maps in Angular 6
Display and Track User's current location using Google Map Geolocation in Angular 5
Post on stackoverflow about Google Maps' infowindow
Create a MEAN Stack Google Map App
How To Implement Password Reset In Node.js
This project was generated with Angular CLI version 7.0.3.
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.
Run ng generate component component-name
to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module
.
Run ng build
to build the project. The build artifacts will be stored in the dist/
directory. Use the --prod
flag for a production build.
Run ng test
to execute the unit tests via Karma.
Run ng e2e
to execute the end-to-end tests via Protractor.
To get more help on the Angular CLI use ng help
or go check out the Angular CLI README.