Connecting to MongoDB Atlas with Mongoose

In MongoDB Atlas on your Cluster page, click Connect > Connect your application > Copy the connection string

Create config folder. Inside, create default.json. With the config package, we can create global values that we can use throughout our application

In default.json:

{
   "mongoURI": "mongodb+srv://username:<password>@devconnector.cc6yr.mongodb.net/<dbname>?retryWrites=true&w=majority"
}

We use curly braces because this is json formatting

Replace <password> with your password. Replace <dbname> with your database’s name.

We could put our connection logic in the server file, but in order to not clutter it up, we can put it in a separate file within the config folder

We’ll call the file db.js (you can call it whatever you want) and this is what goes inside of it:

const mongoose = require('mongoose');
const config = require('config');
const db = config.get('mongoURI');

const connectDB = async () => {
    try {
        await mongoose.connect(db, { useNewUrlParser: true });
        console.log("MongoDB connected...");
    } catch(err) {
        console.log(err.message);
        process.exit(1);
    }
}

module.exports = connectDB;

We add { useNewUrlParser: true } to our connect function in order to get rid of this error:

“(node:58034) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.”

Then, in our server file we can just import and call the connectDB() function:

const express = require("express");
const connectDB = require('./config/db');

const app = express();

connectDB();

app.get('/', (req, res) => res.send('API Running'));

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

About Github Pages

Github Pages is a free solution for deploying your websites to the Internet.

There are three types of GitHub Pages sites:

  1. Project
  2. User
  3. Organization

Project sites are connected to an individual project hosted on GitHub. You can create an unlimited number of project sites. User and organization sites are connected to a specific GitHub account. You only get one user or organization site per Github account.

GitHub Pages source repositories have a recommended limit of 1GB.
GitHub Pages sites have a soft bandwidth limit of 100GB per month.
GitHub Pages sites have a soft limit of 10 builds per hour.

Github Pages publishes any static files that you push to your repository.

Create your own static files OR use a static site generator

You can create a site for yourself or your organization by creating a repository with Github Pages URL as its name and adding web content to its master branch

Benefits of Github Pages
  • Free!!
  • Can use custom domain
  • HTTPS support
  • Ingrained version control in your site
Reasons not to Use Github Pages

You probably think that Github Pages seems perfect, right? Well, it is… for certain types of websites. For small static websites, such as a portfolio website, Github Pages is a perfectly suitable option, but for more involved web applications with complex server implementation, Github Pages is rendered inadequate.

GitHub Pages sites shouldn’t be used for sensitive transactions like sending passwords or credit card numbers.

GitHub Pages is not intended for or allowed to be used as a free web hosting service to run your online business, e-commerce site, or any other website that is primarily directed at either facilitating commercial transactions or providing commercial software as a service (SaaS).

GitHub Pages does not support server-side languages such as PHP, Ruby, or Python.

Netlify

Netlify is a hosting platform that allows you to deploy static websites and front end applications (React, Angular, Vue). The free account offers a lot, but you can also get a pro account.

Netlify makes it simple to get set up and start deploying stuff by allowing you to login in through and deploy repositories from your Github, Gitlab, or Bitbucket account.

Deploying From the Browser

First, login to Netlify with one of these three version control platforms. Then, choose “New Site from Git” and on the next page choose your platform again. It will show you all of your repositories from your account. Choose the branch you want to deploy from (I recommend creating a separate deployment branch so you can still push to your master branch without it affecting your website).

Netlify CLI

Netlify also offers a CLI (command-line interface) tool that you can use to make deployments, etc. as opposed to using their simple online platform.

First, cd into your project directory and type this command: sudo npm i -g netlify-cli. Then, type netlify deploy. In your browser, Netlify CLI will ask for permission to authorize Netlify on your behalf; choose to authorize this. Then, close the window and return back to your Terminal. Answer the prompts on whether it’s a new site and which path to deploy from and you’re done! Netlify will generate a default domain for you to view your site on the Web.

Deploying a React App

We will be deploying the React App from Terminal. Make sure you already have the Netlify CLI installed globally on your system.

First, if you haven’t done so already, you want to build out your static assets using this command in your project directory: npm run build. This will put everything into a build folder. So, now if you ls your directory, you will see a folder called build.

Now you want to run the netlify deploy command (assuming you’ve already installed the CLI). Choose the build folder we created above as the path to deploy. That’s it! You’re site is deployed.

Using a Custom Domain

On the Netlify platform, choose the project which you’d like to give a custom domain. Then, press the “Domain Settings” button. Then press “Add Custom Domain.” Type in the custom domain name you’d like to use (after you’ve already boughten it, of course) and press “Add Domain.” In the Domain Registrar you use, go do any additional configuration / setup you need.

Netlify Forms

Netlify has a built-in form service called Netlify Forms that allows you to manage forms and submissions without any server-side code or JavaScript.

It’s extremely easy to implement this service in your HTML form. Just add the netlify attribute to any form and everything gets wired up automatically. Their bots find your forms by inspecting the HTML of your site before its published.

<form name="contact" netlify>
   <label>Name <input type="text" name="name" /></label>
   <button type="submit">Submit</button>
</form>

What is a Dynamic Website?

How is a dynamic page rendered? When the user requests a site, the server queries one or more databases for content, then passes result to templating engine which formats everything into an HTML file for user (dynamically rendered)

With each request from the end user, the HTML code the user gets back from the server is not always the same. The HTML markup you get back adjusts dynamically on the server

Dynamic: things change on the server and new requests can yield a different file
Static: the files never change, they sit on the server and you always get the same exact version

The server returns a dynamically generated HTML page. That page is not necessarily always the same because the HTML code and even the JS code can be generated on the server

The server is not involved in page rendering after serving the HTML/CSS/JS files. Although, page content can still be changed via JS in the browser)

The server side is not doing anything on the loaded page once it’s in the browser. Dynamic rendering is really about that first render when you send the request and get back a page

Dynamic does NOT mean that there’s no HTML page being served— it’s just built dynamically for each request

  • Finished page is served but needs to be generated first
  • Better for SEO because all the page’s content is available on first load
  • Users don’t have to wait for the data after page loads, but they do have to wait for page to load
  • Security tends to be easy to implement because it’s so common for dynamic sites
  • Requires a hosting service which supports the chosen server-side language (and version). Dynamic hosts tend to be more complex to setup and expensive

AWS EC2/ Elastic Beanstalk, Heroku

What is a Static Website?

A static website is a website that only contains only contains HTML, CSS, and/or (client-side) JS files.

Static simply means that the site is not generated on the server. Instead of being rendered dynamically, the HTML, CSS, and JS just sit there waiting on a server for a user to request them. Every user will see the same version of the files.

Static does NOT mean that the page never changes — it’s just pre-built during development. You can still make pages interactive with client-side JavaScript, API calls, etc. Any rendering/changing that is done happens in the browser.

Rendering in the browser means faster changes because you don’t have to wait for information from the server with each update, but the data needs to be fetched after the initial rendering so the initial rendering is slower than a dynamic website/ server-side rendering.

It’s very important these days that things update constantly and that we give immediate feedback. That tends to be easy with static apps because JavaScript runs in the browser, you don’t need to wait for a response from the server to change things. Although, the first page load is slower with static sites than dynamic sites because the data needs to be fetched from the server after the initial render of the static HTML files.

Some advantages of static websites:

  1. Speed/ performance
  2. Version control for content
  3. Security
  4. Less hassle with the server
  5. Traffic surges
  6. Only static host is needed (i.e. it only needs to serve HTML, JS, CSS)
    • Static hosts tend to be cheaper, setup is typically easier (ex. AWS S3, Firebase Hosting)

Some disadvantages of static websites:

  1. No real-time content
  2. No user input
  3. No admin UI
    • As opposed to the incredibly easy publishing processes of sites such as WordPress or Medium, posts on static sites are typically written in Markdown & require the regeneration of the site (watch functionality does this automatically) in order to publish them and deploy the files to a server
  4. You might get performance issues since server might be more powerful than user’s browser
  5. SEO inefficiencies: search engine may not see the client-side rendered data, it only sees what’s initially on the page
  6. JavaScript in the browser can be dangerous security-wise

How to Use CSS Flexbox

First, set the display of your container div to be flex.

div {
   display: flex;
} 

When you set a container to display: flex, the browser will automatically format the child elements to all be inline with each other. You can use each child’s flex property to define the width that they take up on the line.

The larger the flex value, the more space it will take up compared to the other elements on the line. For example, if there are 2 elements within the flexbox container (an image and a paragraph), if you set the image’s flex property value to 1 and the paragraph’s to 2, the paragraph will take up 2/3 of the space and the image will take up 1/3 of the space.

Horizontally and vertically align child elements within flexbox container

Let’s say I had a header within my flexbox div and I wanted to center it both horizontally and vertically. I would simply set align-items and justify-content to center:

header {
   align-items: center;
   justify-content: center;
}

The align-items property controls alignment of all items on the cross axis and the justify-content property controls alignment of all items on the main axis.

The align-items and align-self properties control alignment of our flex items on the cross axis, down the columns if flex-direction is row and along the row if flex-direction is column.

Main axis: left to right if flex-direction is row; up and down if flex-direction is column

Web Hosting

When you’re developing your website, most times it will only be available on your local system. In order make it accessible to anyone, your website must be hosted on a server. A server is a powerful computer that must stay online 24/7 ready to serve up data for the websites it houses.

Servers are physically located in data centers, which are typically run and managed by different web hosting companies.

There are different types of servers with different benefits and drawbacks, thus there are different types of web hosting.

Types of Web Hosting

  1. Shared Hosting
  2. VPS Hosting
  3. Dedicated Hosting
  4. Cloud Hosting
  5. Methods of Hosting
    1. Managed Hosting
    2. Static Hosting

Shared Hosting

  • Most basic type of hosting
  • Cost-effective
  • Good for small/unpopular websites
  • Share resources w/ other websites on a single server
    • If another website on your server has a traffic spike, it could negatively affect your site’s performance
  • Easy to set up. Doesn’t require much technical knowledge

Great for beginners & small websites; those who don’t require much on-site interaction (10 – 20,000 month visits)

BlueHost

VPS Hosting

Virtual Private Server (VPS) Hosting is a middle-ground between Shared Hosting and Dedicated Hosting. Typically, when a website outgrows Shared Hosting, it will migrate to VPS Hosting.

With VPS Hosting, you are still sharing a server with other websites, but not as many. The server is broken up into smaller “virtual” servers with their own individual configurations.

This hosting benefits tech-savvy website owners because it allows them to make custom changes to their server configuration.

Pros:

  • Dedicated server resources.
  • Ability to make custom configurations to your server.
  • Higher uptime rates and faster loading speeds.
  • More cost-effective than a dedicated server.

Cons:

  • Sharing the main server with other websites.
  • Not as easy to set up as a shared server.
  • Still has limitations in terms of what you can control.

InMotion

Dedicated Hosting

With Dedicated Hosting, you will have a server that belongs to you and only you.

They’re great because…

  • Top of the line in web hosting
  • Site operates at peak performance
  • Complete technical control over server

But they also have problems such as…

  • one of the most expensive web hosting options
  • high level of tech expertise required for installation & management

Dedicated Hosting is mostly for websites that get a high-level of traffic (>100,000 monthly visits), need the highest level of security, and/or need complete control of their server configuration.

HostGator

Cloud Hosting

Cloud hosting is a newer type of web hosting. It can best be described as a hybrid version of a VPS, but more cost-effective.

Unlike traditional hosting in which your website is stored on a single server, cloud hosting plans come with multiple servers, each with its own responsibilities. If one goes down, the others help to pick up the slack, making your website more immune to server malfunctions.

Pros:

  • High security
  • Scale resources on demand & only pay for what you need
  • Less unexpected downtime

Cons:

  • Pricing isn’t always fixed
  • Unpredictable traffic can increase costs
  • Limited customization

Methods of Hosting

I couldn’t really think of the perfect word to differentiate them, so I just went with methods, but basically by “Methods of Hosting” I mean that it is not a different type of server but rather a particular way of using a server / type of web hosting.

Managed Hosting

Managed Hosting isn’t so much a type of hosting as an IT provisioning model. All managed hosting entails is that the hosting company will handle the hardware and software setup, configuration, and maintenance of your server resources. Most hosting packages you will find online are likely to be managed.

Static Hosting

Static Hosting is basically hosting for static websites. Static websites are fixed-content, HTML-based websites that display the same information to all visitors. 

Static websites and static hosting have re-emerged as an effective way of stripping the unnecessary complexities from the (simple) web development process. They are great for performance and simplicity if you don’t need anything rendered on the server.

“Cheap” Static Hosting Options: Bluehost, Hostinger, etc.

Free Static Hosting Options: Github Pages, Netlify, Amazon S3, Firebase

Which option best fits you?

Shared Hosting: The most cost-effective option for low traffic websites

VPS Hosting: websites that have outgrown shared hosting

Dedicated Hosting: Enterprise-level servers for large websites

Cloud Hosting: Works best for websites that are growing rapidly and need scalable resources

How Does the Internet Work?

The Internet is really just a giant wire. It connects every computer in the world (with Internet access) to each other. Two computers in entirely different corners of the world can communicate and transfer data back and forth through the Internet.

Some of these computers attached to the Internet have a very special job. They have to be online 24/7 ready to serve you all of the data and the files that you are requesting when you try to access websites. These computers that are doing that job are called servers. A computer that an everyday user uses to access the Internet is called a client.

Internet Service Provider (ISP): the company you pay to get access to the Internet. In the US, for example, this would be companies like Comcast & AT&T

DNS Server: responsible for translating domain names to numeric IP addresses; Domain Name System Server

IP address: postal address for your computer; every single computer connected to the Internet has an IP address

Internet Backbone: underwater cables that connect across the world that power the Internet

  1. Client requests a website (ex. https://google.com)
  2. Browser sends a message to ISP
  3. ISP relays request to a DNS Server
  4. DNS Server looks up website’s IP address in its database (216.58.210.46)
  5. DNS Server finds the IP address & sends it back to browser
  6. Now knowing the exact address, the client makes a direct request to the address through the ISP
  7. Request goes through ISP then through Internet Backbone and ends up at the Server that is located at the IP address
  8. Server sends all of the files back to client through the Internet Backbone and ISP

Type this IP address into your browser (216.58.210.46) and the browser will serve up the Google Home page.

Internet backbone - Wikipedia
The Internet Backbone’s wires literally span across the entire globe, hidden underwater

How to use the express-validator package

The express-validator package is an npm package that makes it much easier to validate input fields (for user authentication).

First, at the top of our server file, we need to get access to the check and validationResult methods from express-validator:

const { check, validationResult } = require('express-validator/check');

Then, when you are handling the post route of a form, you can implement validation. First, you add a new parameter to the post method; it should be an empty JS array:

app.post('/', [], (req, res) => {
});

Within the array, run the check function on each field and give it the requirements you want to check for. For example, you can check if the input is an email or has a minimum length:

app.post('/', [
   // username must be an email
   check('username').isEmail(),
   // password must be at least 5 chars long
   check('password').isLength({ min: 5 })
], (req, res) => {
});

Then, in the callback, you create a variable called errors to hold any errors from the validation checks in the above array:

app.post('/', [
   check('username').isEmail(),
   check('password').isLength({ min: 5 })
], (req, res) => {
   // Finds the validation errors in this request and puts them in an array called errors
   const errors = validationResult(req);
});

Then, we check if the errors object holds an errors. If so, we can do stuff with the errors. If not, we can do stuff with the inputs:

app.post('/', [
   check('username').isEmail(),
   check('password').isLength({ min: 5 })
], (req, res) => {
   const errors = validationResult(req);

   if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
   }

   User.create({
      username: req.body.username,
      password: req.body.password
   }).then(user => res.json(user));
});

In the event of an error, we send a 400 Bad Request using res.status(400). This simply means that things didn’t go as planned. Then, we get an array of error messages that correspond with the input validations that failed. The json response object will look something like this:

{
   "errors": [
      {
         "location": "body",
         "params": "username",
         "msg": "Insert custom or default error message here",
      }, 
      {
         "location": "body",
         "params": "password",
         "msg": "Please enter a correct password",
      }
   ]
}

More on the check function

We can pass a second optional parameter into the check function which will serve as a custom error message. If we don’t pass this parameter, it will give some generic error message.

check('name', 'Name is required')

Check if a field is empty

check('name', 'Name is required').not().isEmpty()

What is React.js?

React.js is a JavaScript library for building user interfaces. It is a front-end web framework. React.js breaks down the user interface into customizable components. It combines pieces of HTML, CSS, and JavaScript in each component. It allows the browser to refresh a single component without having to refresh the entire page. It is one of the most popular and in-demand web frameworks

Most people put all of their body content within a div with the id “root.” This is React convention.

<div id="root">
</div>

Before we can start coding, we must install our dependencies

npm i react react-dom
ReactDOM.render(WHAT TO SHOW, WHERE TO SHOW it, optional callback after render function completed)
var React = require("react");
var ReactDOM = require("react-dom");

ReactDOM.render(<h1>Hello world!</h1>, document.getElementById("root"));

React works by creating these JSX files. HTML is inputted into compiler which converts it into Vanilla JavaScript. The compiler comes from including the React module.

Inside the React Module, there is something called Babel. Babel is a JavaScript compiler. It’s able to take next-gen JavaScript (es6, es7, es8) and compile it down to a version that any browser can understand. This includes compiling JSX into plain JS.

var h1 = document.createElement("h1");
h1.innerHTML = "Hello World!";
document.getElementById("root").appendChild(h1)
import React from "react";
import ReactDOM from "react-dom";

Render method can only take a single HTML element. If you put two back-to-back, it will crash. The way around this is wrapping n elements into a div, so that it’s “1 element.”

ReactDOM.render(
<div>
   <h1>Hello world!</h1>
   <p>This is the first paragraph.</p>
</div>, 
document.getElementById("root")
);
const name = "Joshua";

ReactDOM.render(<h1>Hello {name}!</h1>, document.getElementById("root"));
const num = 4;

ReactDOM.render(<p>Your lucky number is {num}!</p>, document.getElementById("root"));
ReactDOM.render(<p>Your lucky number is {Math.floor(Math.random() * 10)}!</p>, document.getElementById("root"));

You can add any JavaScript value or expression inside the curly braces, but you can’t write JavaScript statements(if statements, etc.)

Styling

External Stylesheets

<h1 class="heading">Title</h1> // no 
<h1 className="heading">Title</h1> // yes

Although it looks like HTML, it’s JSX. It’s being converted to Vanilla JavaScript. There is no “class” property in JS; the correct JS equivalent is the className property.

HTML uses all lowercase. When we write JSX we use camel case because JS uses camel case.

contenteditable vs contentEditable

<h1 contentEditable="true" spellCheck="false">My Favourite Foods</h1>

It is recommended to do all of your styling in an external CSS file then apply those styles to your JSX content with class and id tags.

.heading {
   color: 'red';
}
<h1 className="heading">My Favorite Foods</h1>

Inline Styling

The style property requires a JavaScript object

JavaScript object

{
  key: value,
}
<h1 style="color: 'red'">My Title</h1> // no
<h1 style={{color: 'red'}}>My Title</h1> // yes

Any JavaScript within HTML must be wrapped in curly braces. JavaScript objects must be wrapped in curly braces. Thus, 2 sets of curly braces

const customStyle = {
  color: "red",         // use commas instead of semicolons
  fontSize: "20px",     // font-size becomes fontSize
  border: "1px solid #000" // every value goes in quotes
}

customStyle.color = "blue";  // change styles after definition

ReactDOM.render(
  <div>
    <h1 style={customStyle}>My Favourite Foods</h1>
  </div>,
  document.getElementById("root")
);

React Components

We always capitalize the names of our components because that’s how React differentiates that they are custom components

function Heading() {
   return <h1>My Heading!</h1>
}

ReactDOM.render(
   <div>
      <Heading />
   </div>,
   document.getElementById("root")
);

In the same folder, create a new file called “Heading.jsx”

All of our components separated into individual files with the .jsx extension

import React from "react";

function Heading() {
   return <h1>My Heading!</h1>;
}

export default Heading;

Don’t use parentheses. That will make it run immediately; we want to use it as a component

import React from "react";
import ReactDOM from "react-dom";
import Heading from "./Heading";

Most times, you won’t see any div or child elements in the index.js file. Instead, it will just be a single App custom component.

import React from "react";
import Heading from "./Heading";   // child component
import List from "./List";         // child component

function App(){
   return <div>
      <Heading />
      <List />
   </div>
}

export default App;
ReactDOM.render(
   <App />,
   document.getElementById("root")
);

Create a components folder and put all of your components in it

  • src
    • components
      • App.jsx
      • Heading.jsx
      • List.jsx
  • public
    • index.html
    • styles.css
import App from "./components/App";