mongoseを使用してmongodbをノードとします.jsは4->delete、patch、put(これらのAPI表現)を使用する


カート機能の追加


ビューフォルダのCart。ejs

            <!DOCTYPE html>
            <html lang="en">
              <head>
                <!-- Required meta tags -->
                <meta charset="utf-8" />
                <meta
                  name="viewport"
                  content="width=device-width, initial-scale=1, shrink-to-fit=no"
                />
                <link rel="icon" href="/static/favicon.ico" type="image/x-icon" />
                <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
                <!-- Bootstrap CSS -->
                <link
                  rel="stylesheet"
                  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
                  integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
                  crossorigin="anonymous"
                />

                <!-- Font Awesome CSS -->
                <link
                  href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
                  rel="stylesheet"
                />
                <!-- Optional JavaScript -->
                <!-- jQuery first, then Popper.js, then Bootstrap JS -->
                <script
                  src="https://code.jquery.com/jquery-3.5.1.js"
                  integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
                  crossorigin="anonymous"
                ></script>
                <script
                  src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
                  integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
                  crossorigin="anonymous"
                ></script>
                <script
                  src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
                  integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s"
                  crossorigin="anonymous"
                ></script>
                <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script>

                <link href="/static/mystyle.css" rel="stylesheet" />
                <title>스파르타 쇼핑몰 | 장바구니</title>
                <script>
                  $(document).ready(function() {
                    get_goods();
                    $("#categorySelect").on("change", function() {
                      get_goods($(this).val());
                    });
                  });

                  function sign_out() {
                    $.removeCookie("mytoken", { path: "/" });
                    $.removeCookie("userName", { path: "/" });
                    window.location.href = "/";
                  }

                  function get_goods() {
                    $("#goodsList").empty();
                    $.ajax({
                      type: "GET",
                      url: `/api/cart`,
                      data: {},
                      success: function(response) {
                        let goods = response["cart"];
                        for (let i = 0; i < goods.length; i++) {
                          make_card(goods[i]["goods"]);
                        }
                        getSum();
                      }
                    });
                  }

                  function order() {
                    $.ajax({
                      type: "GET",
                      url: `/api/cart`,
                      data: {},
                      success: function(response) {
                        let goods = response["cart"];
                        let cart = [];
                        for (let i = 0; i < goods.length; i++) {
                          cart.push({
                            goodsName: goods[i]["name"],
                            quantity: goods[i]["goodsId"]
                          });
                        }
                        sessionStorage.setItem("cart", JSON.stringify(cart));
                        window.location.href = "/order";
                      }
                    });
                  }

                  function make_card(item) {
                    let htmlTemp = `<div class="card mb-2">
                                                <div class="row no-gutters">
                                                    <div class="col-4" style="background: #868e96;" onclick="location.href='/detail?goodsId=${
                                                      item["goodsId"]
                                                    }'">
                                                        <img src="${item["thumbnailUrl"]}"
                                                             class="card-img-top h-100" alt="...">
                                                    </div>
                                                    <div class="col-8">
                                                        <div class="card-body py-1">
                                                            <div class="card-title row mt-2">
                                                                <p class="font-weight-bold col" style="display: inline">${
                                                                  item["name"]
                                                                }</p>
                                                                <span class="card-price col text-right">$${number2decimals(
                                                                  item["price"]
                                                                )}</span>

                                                            </div>
                                                            <div class="form-group row mr-0">
                                                                <div class="col-7 pr-2">
                                                                    <button class="btn btn-outline-sparta btn-block" onclick="removeItem(${
                                                                      item["goodsId"]
                                                                    })">삭제</button>
                                                                </div>
                                                                <select class="custom-select col-5" id="numberSelect-${
                                                                  item["goodsId"]
                                                                }">
                                                                    <option selected value=1>1</option>
                                                                    <option value=2>2</option>
                                                                    <option value=3>3</option>
                                                                </select>
                                                            </div>

                                                        </div>


                                                    </div>
                                                </div>
                                            </div>`;
                    $("#goodsList").append(htmlTemp);
                    $(`#numberSelect-${item["goodsId"]}`).change(function() {
                      // console.log(parseInt($(this).val()))
                      $.ajax({
                        type: "PATCH",
                        url: `/api/goods/${item["goodsId"]}/cart`,
                        data: {
                          quantity: parseInt($(this).val())
                        },
                        success: function(response) {
                          if (response["result"] == "success") {
                            console.log(response["msg"]);
                            getSum();
                          }
                        }
                      });
                    });
                  }

                  function removeItem(goodsId) {
                    $.ajax({
                      type: "DELETE",
                      url: `/api/goods/${goodsId}/cart`,
                      data: {},
                      success: function(response) {
                        if (response["result"] == "success") {
                          get_goods();
                        }
                      }
                    });
                  }

                  function getSum() {
                    let $prices = $(".card-price");
                    let $selects = $("select");
                    if ($prices.length != $selects.length) {
                      console.log("길이가 맞지 않습니다.");
                      return;
                    }
                    let sum = 0;
                    for (let i = 0; i < $prices.length; i++) {
                      let price = parseFloat(
                        $($prices[i])
                          .text()
                          .replace("$", "")
                      );
                      let count = parseInt($($selects[i]).val());
                      // console.log(price, count)
                      sum += price * count;
                    }
                    $("#priceSum").text("$" + number2decimals(sum));
                    sessionStorage.setItem("priceSum", number2decimals(sum));
                  }

                  function number2decimals(num) {
                    return (Math.round(num * 100) / 100).toFixed(2);
                  }
                </script>
                <style>
                  .card {
                    cursor: pointer;
                  }
                </style>
              </head>

              <body>
                <nav
                  class="navbar navbar-expand-sm navbar-dark bg-sparta justify-content-end"
                >
                  <a class="navbar-brand" href="/goods">
                    <img
                      src="/static/logo_big_tr.png"
                      width="30"
                      height="30"
                      class="d-inline-block align-top"
                      alt=""
                    />
                    스파르타 쇼핑몰
                  </a>
                  <button
                    class="navbar-toggler ml-auto"
                    type="button"
                    data-toggle="collapse"
                    data-target="#navbarSupportedContent"
                    aria-controls="navbarSupportedContent"
                    aria-expanded="true"
                    aria-label="Toggle navigation"
                  >
                    <span class="navbar-toggler-icon"></span>
                  </button>
                  <div
                    class="navbar-collapse collapse flex-grow-0 ml-auto"
                    id="navbarSupportedContent"
                    style=""
                  >
                    <ul class="navbar-nav mr-auto text-right">
                      <li class="nav-item" id="link-cart">
                        <a class="nav-link" href="/cart">
                          장바구니<i
                            class="fa fa-shopping-cart ml-2"
                            aria-hidden="true"
                          ></i>
                        </a>
                      </li>
                      <li class="nav-item" id="link-logout">
                        <a class="nav-link" data-toggle="modal" data-target="#signOutModal">
                          로그아웃<i class="fa fa-sign-out ml-2" aria-hidden="true"></i>
                        </a>
                        <div
                          class="modal text-left"
                          id="signOutModal"
                          tabindex="-1"
                          role="dialog"
                          aria-labelledby="signOutModalLabel"
                          aria-hidden="true"
                        >
                          <div class="modal-dialog" role="document">
                            <div class="modal-content">
                              <div class="modal-header">
                                <h5 class="modal-title" id="signOutModalLabel">로그아웃</h5>
                                <button
                                  type="button"
                                  class="close"
                                  data-dismiss="modal"
                                  aria-label="Close"
                                >
                                  <span aria-hidden="true">&times;</span>
                                </button>
                              </div>
                              <div class="modal-body">
                                로그아웃하시면 장바구니가 사라져요!
                              </div>
                              <div class="modal-footer">
                                <button
                                  type="button"
                                  class="btn btn-outline-sparta"
                                  data-dismiss="modal"
                                >
                                  취소
                                </button>
                                <button
                                  type="button"
                                  class="btn btn-sparta"
                                  onclick="sign_out()"
                                >
                                  로그아웃하기
                                </button>
                              </div>
                            </div>
                          </div>
                        </div>
                      </li>
                    </ul>
                  </div>
                </nav>
                <div class="wrap">
                  <div class="mb-3">
                    <h4>
                      <i class="fa fa-shopping-cart mr-1" aria-hidden="true"></i>장바구니
                    </h4>
                  </div>
                  <div id="goodsList">
                    <div class="card mb-2" onclick="location.href='#'">
                      <div class="row no-gutters">
                        <div class="col-4" style="background: #868e96;">
                          <img
                            src="https://cdn.pixabay.com/photo/2016/09/07/19/54/wines-1652455_1280.jpg"
                            class="card-img-top h-100"
                            alt="..."
                          />
                        </div>
                        <div class="col-8">
                          <div class="card-body py-1">
                            <div class="card-title row mt-2">
                              <p class="font-weight-bold col" style="display: inline">
                                상품 1
                              </p>
                              <span class="card-price col text-right">$6.20</span>
                            </div>
                            <div class="form-group row mr-0">
                              <div class="col-7 pr-2">
                                <button class="btn btn-outline-sparta btn-block">
                                  삭제
                                </button>
                              </div>
                              <!--                                    <label for="numberSelect" class="col col-form-label">수량</label>-->
                              <select class="custom-select col-5" id="numberSelect">
                                <option selected value="1">1</option>
                                <option value="2">2</option>
                                <option value="3">3</option>
                              </select>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <hr />

                  <div class="row mb-3">
                    <div class="col-5">총 상품금액</div>
                    <div class="col-7 text-right" id="priceSum">$6.20</div>
                  </div>
                  <button type="button" class="btn btn-sparta btn-block" onclick="order()">
                    구매
                  </button>
                </div>
              </body>
            </html>
            
            

routerフォルダのgoods。js 1に追加


-->カートにデータを入れるためのapi
        const Cart = require("../schemas/cart");

      router.post("/goods/:goodsId/cart", async (req, res) => {
        const { goodsId } = req.params;
        const { quantity } = req.body;

        isCart = await Cart.find({ goodsId });
        console.log(isCart, quantity);
        if (isCart.length) {
          await Cart.updateOne({ goodsId }, { $set: { quantity } });
        } else {
          await Cart.create({ goodsId: goodsId, quantity: quantity });
        }
        res.send({ result: "success" });
      });
このセクションでは、データを公開します-->非同期割当て
router.post("/goods/:goodsId/cart", async (req, res) => {
        const { goodsId } = req.params;
        const { quantity } = req.body;
        
        
-->goodsIdはurlで受信-->コードの構造によりpathにデータのidが表示される(前のコードを参照)
-->数bodyのデータを介して-->post形式のapiリクエストを受信した場合、bodyに含まれるデータ
このセクションでは、カートに追加するデータがmongodyにすでに存在するかどうかを確認します.
   isCart = await Cart.find({ goodsId });
            console.log(isCart, quantity);
            if (isCart.length) {
              await Cart.updateOne({ goodsId }, { $set: { quantity } });
            } else {
              await Cart.create({ goodsId: goodsId, quantity: quantity });
            }
            res.send({ result: "success" });
          });
-->データが既に存在する場合は、データの数量部分のみを変更-->数量部分]
Cart.updateOne({ goodsId }, { $set: { quantity } });
----->goodsId上書きデータ数分
-->データがない場合は、IDと数を含むデータを挿入します.
Cart.create({ goodsId: goodsId, quantity: quantity });

routerフォルダのgoods。js 2に追加


-->カートのデータを取得するためのapi
    router.get("/cart", async (req, res) => {
    const cart = await Cart.find({});
    const goodsId = cart.map(cart => cart.goodsId);

    goodsInCart = await Goods.find()
      .where("goodsId")
      .in(goodsId);

    concatCart = cart.map(c => {
      for (let i = 0; i < goodsInCart.length; i++) {
        if (goodsInCart[i].goodsId == c.goodsId) {
          return { quantity: c.quantity, goods: goodsInCart[i] };
        }
      }
    });

    res.json({
      cart: concatCart
    });
  });
この部分では,Cart(mongody)のすべてのデータをインポートし,idのみを抽出する.
    router.get("/cart", async (req, res) => {
    const cart = await Cart.find({});
    const goodsId = cart.map(cart => cart.goodsId);
    
-->つまり、ショッピングバスケットのデータのidはgoodsId変数にリスト形式で割り当てられる.
この部分では、買い物かごの中のデータに対応する情報をデータ全体から取得する.
    goodsInCart = await Goods.find()
      .where("goodsId")
      .in(goodsId);
-->Cart DBはgoodsIdと数のみ
-->Goods DBにはgoods Id、画像アドレス、タイトルなど、goods Idに対応する商品情報があります.
-->そこで、Cartのgoods Idに関する情報に基づき、goodsはこの3品の情報をgoods InCartにインポートして保存します.
この部分では,Cart中のデータとGoods中のデータをgoodsIdを基準としてJoinする.
    concatCart = cart.map(c => {
      for (let i = 0; i < goodsInCart.length; i++) {
        if (goodsInCart[i].goodsId == c.goodsId) {
          return { quantity: c.quantity, goods: goodsInCart[i] };
        }
      }
    });
    
    
このセクションでは、cartというjson形式でデータが生成され、応答されます.
      res.json({
            cart: concatCart
          });
          
          

カートからデータを削除


routerフォルダのgoods。jsに追加

    router.delete("/goods/:goodsId/cart", async (req,res)=>{
      const { goodsId } = req.params;

      const isGoodsInCart= await Cart.find({ goodsId });
      if (isGoodsInCart.length > 0){
        await Cart.deleteOne({goodsId});
      }

      res.send({result : "success"});
    })
    
-->mongodbからデータを削除するためのdelete表現のapi
-->deleteの特徴-->postなどの表現はget表現とは異なり、通常bodyは使用されません
-->誰かを削除しますが、==>その他の情報は必要ありません.
-->削除するデータがデータベースに存在するかどうかを確認します.
次のコードで削除
  await Cart.deleteOne({ goodsId });
  
  
  

データの表示を削除するdelete


データを削除するapi.
-->詳細については、上記のコードを参照してください

数量部分をカートからのデータ更新に設定



-->数量部分が変更された場合、変更はmongodbに保存されます

cart.ejsで当該領域を担当するhtml、jsコードの一部

        $(`#numberSelect-${item["goodsId"]}`).change(function() {
              // console.log(parseInt($(this).val()))
              $.ajax({
                type: "PATCH",
                url: `/api/goods/${item["goodsId"]}/cart`,
                data: {
                  quantity: parseInt($(this).val())
                },
                success: function(response) {
                  if (response["result"] == "success") {
                    console.log(response["msg"]);
                    getSum();
                  }
                }
              });
            });
-->goodsIdに基づいてデータを区別し、数量部分の変更を検出します.
リクエストの送信
リクエスト内容
                type: "PATCH",
                url: `/api/goods/${item["goodsId"]}/cart`,
                data: {
                  quantity: parseInt($(this).val())
                },
                
                
                
リクエストが正常に処理され、応答が受信されたときのコンテンツ
                 success: function(response) {
                  if (response["result"] == "success") {
                    console.log(response["msg"]);
                    getSum();
                  }
                  
注記-->getSum関数-->数に応じて値を変更するように構成されている関数
          function getSum() {
          let $prices = $(".card-price");
          let $selects = $("select");
          if ($prices.length != $selects.length) {
            console.log("길이가 맞지 않습니다.");
            return;
          }
          let sum = 0;
          for (let i = 0; i < $prices.length; i++) {
            let price = parseFloat(
              $($prices[i])
                .text()
                .replace("$", "")
            );
            let count = parseInt($($selects[i]).val());
            // console.log(price, count)
            sum += price * count;
          }
          $("#priceSum").text("$" + number2decimals(sum));
          sessionStorage.setItem("priceSum", number2decimals(sum));
        }

routerフォルダにgoodsを入力して、上記のコードの要求を受信します。jsファイルのapiコード

          router.patch("/goods/:goodsId/cart", async (req,res) =>{
            const {goodsId} = req.params;
            const {quantity} = req.body;

            const isGoodsInCart = await Goods.find({goodsId});
            if (isGoodsInCart.length > 0){
              await Cart.updateOne({ goodsId },{$set: {quantity}})
            }

            res.send({ result : "success" });
          })
          
-->更新するデータがmongodyに存在するかどうかを確認
-->あれば下記のコードでmongodbのデータを更新できます
     await Cart.updateOne({ goodsId },{$set: {quantity}})
     
----->goodsIdに含まれるコンテンツのデータは、数量部分を数量部分に置き換えます
(非同期割当方式と見なすことができる.)

プレゼンテーションputとpatch更新データ


-->データベース内のデータを変更する場合はputとpatchを使用します.
両者を使い分けるのが一般的です.(そうする必要はありません)

put


通常、データのすべての内容を変更するために使用されます.
-->たとえば)
id、名前、年齢、性別、アドレスの5つのプロパティのアーキテクチャデータベース:
id=25のデータを修正する場合
put(25、林秀智、27、女、ヒキガエル)を使用して、このモードのすべての属性を入力してデータを変更します.

patch


通常、データの一部を変更するために使用されます.
-->たとえば)
id、名前、年齢、性別、アドレスの5つのプロパティのアーキテクチャデータベース:
id=25のデータを修正する場合
patch(25、金庫)を使用して、データのいくつかの属性を変更します.
------>ここで、「アドレス」という名前の値を「アドレス」という名前の変数に挿入します.これは、スキーマ内の属性に非同期で値を割り当て、どの属性の値を変更するかを示します.