Node.js-Tutorial 2023 for Bigginer, Deploy to Heroku

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/4242b874-7bd2-1a1a-5da7-db7cfef62b41.png)


https://nodejs.org/ja/

https://www.youtube.com/playlist?list=PL4cUxeGkcC9jsz4LDYc6kv3ymONOKxwBU

https://github.com/iamshaunjp/node-crash-course


# Nodejs Version
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/a4e164e8-1851-9817-263c-2cd1243e4b3c.png)

# Modules
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/d843c817-4929-34ae-41f9-6ebc744c4168.png)

# 1 Global Object & __dirname, __filename
```javascript:main.js
// Global Object

console.log(global);

// __dirname, __filename
console.log(__dirname);
console.log(__filename);
```

# 2 Filesystem
```javascript:main.js
const fs = require("fs");

// reading files
fs.readFile("./docs/blog1.txt", (err, data) => {
  if (err) {
    console.log(err);
  }
  console.log(data.toString());
});

// writing files
fs.writeFile("./docs/blog2.txt", "Hello world", () => {
  console.log("file was written");
});

// directories
if (!fs.existsSync("./assets")) {
  fs.mkdir("./assets", (err) => {
    if (err) {
      console.log(err);
    }
    console.log("folder created");
  });
} else {
  // remove folder
  fs.rmdir("./assets", (err) => {
    if (err) {
      console.log(err);
    }
    console.log("folder deleted");
  });
}

// deletting files
if (fs.existsSync("./docs/deleteme.txt")) {
  fs.unlink("./docs/deleteme.txt", (err) => {
    if (err) {
      console.log(err);
    }
    console.log("file deleted");
  });
} else {
  fs.writeFile("./docs/deleteme.txt", "Delete me", () => {
    console.log("file was written 'deleteme.txt'");
  });
}
```

# 3 Stream
```javascript:main.js
const fs = require("fs");

const readStream = fs.createReadStream("./docs/blog3.txt", {
  encoding: "utf-8",
});
const writeStream = fs.createWriteStream("./docs/blog4.txt");
readStream.on("data", (chunk) => {
  console.log("------ NEW CHUNK ------");
  console.log(chunk);
  writeStream.write("\nNEW CHUNK\n");
  writeStream.write(chunk);
});

// piping
readStream.pipe(writeStream);
```

# 4 Http
```javascript:main.js
const fs = require("fs");
const http = require("http");

// http
const server = http.createServer((req, res) => {
  console.log(req.url, req.method);

  // set header content type
  res.setHeader("Content-Type", "text/html");

  let path = "./views/";
  switch (req.url) {
    case "/":
      path += "index.html";
      res.statusCode = 200;
      break;
    case "/about":
      path += "about.html";
      res.statusCode = 200;
      break;
    case "/about-me":
      res.setHeader("Location", "about");
      res.statusCode = 301;
      res.end();
      break;
    default:
      path += "404.html";
      res.statusCode = 400;
      break;
  }

  // send an html file
  fs.readFile(path, (err, data) => {
    if (err) {
      console.log(err);
      res.end();
    } else {
      res.write(data);
      res.end();
    }
  });
});

server.listen(3000, "localhost", () => {
  console.log("listening for requests on port 3000");
});
```


# express
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/15b0f6f5-44b6-5aac-452f-3e46a7166ada.png)

```javascript:app.js
const express = require("express");
const PORT = 3000;

// express app
const app = express();

app.get("/", (req, res) => {
  res.sendFile("./views/index.html", { root: __dirname });
});

app.get("/about", (req, res) => {
  res.sendFile("./views/about.html", { root: __dirname });
});

// redirects
app.get("/about-us", (req, res) => {
  res.redirect("/about");
});

// 404 page
app.use((req, res) => {
  res.status(404).sendFile("./views/404.html", { root: __dirname });
});

// listen for requests
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});


```

# express with template ejs
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/7a8de6f5-973c-37ee-daff-841e8e8c964f.png)

```javascript:app.js
require("dotenv").config();
const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const mongoose = require("mongoose");
const Blog = require("./models/blog");
const blogRoutes = require("./routes/blogRoutes");
const PORT = process.env.PORT;

// express app
const app = express();

// connect to mongodb
mongoose.set("strictQuery", false);
mongoose
  .connect(process.env.MONGO_URI)
  .then(() => {
    console.log("connected to mongodb");
    // listen for requests
    app.listen(PORT, () => {
      console.log(`Server is running on port ${PORT}`);
    });
  })
  .catch((error) => {
    console.log(error.message);
  });

// register view engine
app.set("view engine", "ejs");
app.use((req, res, next) => {
  console.log("--- new request made ---");
  console.log("host: ", req.hostname);
  console.log("path: ", req.path);
  console.log("method: ", req.method);
  next();
});
app.use(morgan("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

// middleware & static files
app.use(express.static("public"));

app.get("/", async (req, res) => {
  const response = await fetch("http://localhost:4000/blogs");
  const blogs = await response.json();
  res.render("index", { title: "Home", blogs });
});

app.get("/about", (req, res) => {
  res.render("about", { title: "About" });
});

// blog route
app.use("/blogs", blogRoutes);

// mongoose and mongo sandbox routes
app.get("/add-blog", async (req, res) => {
  const blog = new Blog({
    title: "third blog",
    snippet: "about my new blog",
    body: "more about my new blog",
  });

  await blog
    .save()
    .then((result) => {
      res.status(200).send(result);
    })
    .catch((err) => {
      console.log(err);
    });
});

app.get("/all-blogs", async (req, res) => {
  await Blog.find()
    .then((result) => {
      res.status(200).json(result);
    })
    .catch((error) => {
      console.log(error);
    });
});

app.get("/single-blog", async (req, res) => {
  Blog.findById("63bad56ebf02aa3a6a0e8059")
    .then((result) => {
      res.status(200).json(result);
    })
    .catch((error) => {
      console.log(error);
    });
});

// 404 page
app.use((req, res) => {
  res.render("./blogs/404", { title: "404" });
});
```


# routes
```javascript:blogRoutes.js
const express = require("express");
const {
  getAllBlogs,
  createBlog,
  getSingleBlog,
  deleteBlog,
  createGetForm,
} = require("../controllers/blogController");
const router = express.Router();

router.route("/").get(getAllBlogs).post(createBlog);

router.get("/create", createGetForm);

router.route("/:id").get(getSingleBlog).delete(deleteBlog);

// router.get("/", getAllBlogs);
// router.post("/", createBlog);

// router.get("/:id", getSingleBlog);
// router.delete("/:id", deleteBlog);

module.exports = router;
```

# controller
```javascript:blogController.js
const Blog = require("../models/blog");

const getAllBlogs = async (req, res) => {
  await Blog.find()
    .sort({ createdAt: -1 })
    .then((result) => {
      res.render("./blogs/index", { title: "All Blogs", blogs: result });
    })
    .catch((err) => {
      console.log(err);
    });
};

const createGetForm = (req, res) => {
  res.render("./blogs/create", { title: "Create" });
};

const createBlog = async (req, res) => {
  const blog = new Blog(req.body);
  await blog
    .save()
    .then((result) => {
      res.redirect("/blogs");
    })
    .catch((error) => {
      console.log(error);
    });
};

const getSingleBlog = async (req, res) => {
  const id = req.params.id;
  await Blog.findById(id)
    .then((result) => {
      res.render("./blogs/details", { title: "Blog Details", blog: result });
    })
    .catch((error) => {
      res.status(404).render("./blogs/404", { title: "Blog not found" });
    });
};

const deleteBlog = async (req, res) => {
  const id = req.params.id;

  await Blog.findByIdAndDelete(id)
    .then((result) => {
      res.status(200).json({ redirect: "/blogs" });
    })
    .catch((error) => {
      console.log(error);
    });
};

module.exports = {
  getAllBlogs,
  createGetForm,
  createBlog,
  getSingleBlog,
  deleteBlog,
};
```

# 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/3c4cd3b6-f075-de75-dd00-f6701d73c6ea.png)


# NPM package

https://www.npmjs.com/package/cors

https://www.npmjs.com/package/dotenv

https://www.npmjs.com/package/express

https://www.npmjs.com/package/ejs

https://www.npmjs.com/package/json-server

https://www.npmjs.com/package/mongoose

https://www.npmjs.com/package/morgan

https://www.npmjs.com/package/nodemon