Skip to main content

Command Palette

Search for a command to run...

[TIL] Toy Project Day 4 - Like & Delete Button User Control Feature & Presentation, Deployment

03/30/23

Updated
[TIL] Toy Project Day 4 - Like & Delete Button User Control Feature & Presentation, Deployment

Reading User Login Token Cookie

token_receive = request.cookies.get("mytoken")
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=["HS256"])
        userid = payload["id"]
        user_info = db.user.find_one({ "id": userid })
        nickname = user_info["nick"]
        return render_template("index.html", nickname=nickname )
    except:
        return render_template("index.html")

Like Button

Logic

  1. Contain the store id in the "liked_store" array attribute under users DB

  2. When the user is not logged in, the Like button is disabled

  3. When the user is logged in,

    1. check if the user already clicked the store

      1. FE: increase the like count number on the page and push store id to the liked_store array

      2. BE: send the store id to the /likeUp API

        1. /likeUp API will increase the like attribute's number by 1 under the store's DB

        2. /likeUp API will add the store id into "liked_store" array under the user's DB

    2. check if the user has not clicked the store

      1. check if the user already clicked the store

        1. FE: increase the like count number on the page and push store id to the liked_store array

        2. BE: send the store id to the /likeDown API

          1. /likeDownAPI will decrease the like attribute's number by 1 under the store's DB

          2. /likeDownAPI will delete the store id into "liked_store" array under the user's DB

Code

# Like button
@app.route("/likeUp", methods=["POST"])
def like_up():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        userid = payload["id"]

        store_id_receive = request.form["id_give"]

        # get current like count number 
        like = db.stores.find_one({"_id": ObjectId(store_id_receive)}, {"like": 1})
        num_like = int(like["like"]) + 1

        # update the like number of store on DB
        add_like = {"$set": {"like": num_like}}
        db.stores.update_one({"_id": ObjectId(store_id_receive)}, add_like)

        # add the info that the user clicked the store in DB
        # the way to append val to the array in MongoDB
        add_liked_store = {'$addToSet': {'liked_store': store_id_receive}}
        db.user.update_one({'id': userid}, add_liked_store)

        return jsonify({"msg": "You added Like"})

    except jwt.ExpiredSignatureError:
        return redirect(url_for("go_login", msg="Login time is expired"))
    except jwt.exceptions.DecodeError:
        return redirect(url_for("go_login", msg="No user found"))


@app.route("/likeDown", methods=["POST"])
def like_down():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        userid = payload["id"]

        store_id_receive = request.form["id_give"]

        like = db.stores.find_one({"_id": ObjectId(request.form["id_give"])}, {"like": 1})
        num_like = int(like["like"]) - 1

        add_like = {"$set": {"like": num_like}}
        db.stores.update_one({"_id": ObjectId(request.form["id_give"])}, add_like)
        # the way to delete specific value from array in DB
        delete_liked_store = {'$pull': {'liked_store': store_id_receive}}
        db.user.update_one({'id': userid}, delete_liked_store)

        return jsonify({"msg": "You deleted Like"})

    except jwt.ExpiredSignatureError:
        return redirect(url_for("go_login", msg="Login time is expired"))
    except jwt.exceptions.DecodeError:
        return redirect(url_for("go_login", msg="No user found"))
$(".like").click(function () {
                let storeid = this.value;
                // Like 1 increasing part
                if (!liked_store.includes(storeid)) {
                    // FE - number changed without refreshing page
                    $(this).removeClass("is-light");
                    $(this).html(function (i, val) {
                        return `&#128077 ${val.split(" ")[1] * 1 + 1}`;
                    });

                    // FE - add store id to liked_store array
                    liked_store.push(storeid);

                    // BE - send the changed count to DB
                    let formData = new FormData();
                    formData.append("id_give", this.value);
                    fetch("/likeUp", { method: "POST", body: formData })
                        .then((response) => response.json())
                        .then((data) => {});
                }
                // Like 1 decreasing part
                else if (liked_store.includes(storeid)) {
                    $(this).addClass("is-light");
                    $(this).html(function (i, val) {
                        return `&#128077 ${val.split(" ")[1] * 1 - 1}`;
                    });

                    // FE - remove store id to liked_store array
                    liked_store = liked_store.filter((s) => {
                        return s !== storeid;
                    }); // THIS PART REQUIRES IMPROVEMENT FOR SUSTAINABILITY AND SPEED

                    let formData = new FormData();
                    formData.append("id_give", this.value);
                    fetch("/likeDown", { method: "POST", body: formData })
                        .then((response) => response.json())
                        .then((data) => {});
                }
            });
// style is applied when refreshing the page
                // when user is not logged in
                if (userid === null) {
                    temp_html_2 = `<div class="store-btn">
                                        <button type="button" class="like button is-warning" title="Disabled button" disabled value=${id}>&#128077 ${like}</button>
                                   </div>
                                </div>
                            </div>`;
                }
                // when user already clicked Like
                else if (liked_store.includes(id)) {
                    temp_html_2 = `<div class="store-btn">
                                            <button type="button" class="button is-danger modify" name=${writerId} value=${id}>수정</button>
                                            <button type="button" class="like button is-warning" value=${id}>&#128077 ${like}</button>
                                   </div>
                                </div>
                            </div>`;
                }
                // when user hasn't click Like
                else {
                    temp_html_2 = `<div class="store-btn">
                                        <button type="button" class="button is-danger modify" name=${writerId} value=${id}>수정</button>
                                        <button type="button" class="like button is-warning is-light" value=${id}>&#128077 ${like}</button>
                                   </div>
                                </div>
                            </div>`;
                }
                temp_html = temp_html_1.concat(temp_html_2);
                $("#cards").append(temp_html);

Delete/Update Button

Logic

  1. Add the writer id to store API to distinguish the writer of the post

  2. When clicking the Delete button, check if the currently logged-in user is the writer of the post

    1. If so, perform the delete function

    2. If not, show an alert message

Code

$(".delete").click(function () {
                console.log(this.name, userid);
                if (this.name == userid) { // <button name=${writerId}>
                    let formData = new FormData();
                    formData.append("id_give", this.value);
                    console.log(this.value);
                    fetch("/store", { method: "DELETE", body: formData })
                        .then((response) => response.json())
                        .then((data) => {
                            window.location.reload();
                        });
                } else {
                    alert("No permission to delete");
                }
            });

Deployment

How to keep the server running when the bash is terminated

nohup python3 app.py

How to stop the server running by nohup

  1. Check the pid (process id) -> sudo lsof -t -i:[port number]

  2. Kill the process -> kill -9 [pid]

Extra: change domain name (matching IP and name server) & OG tag

Today I Learned

Part 1 of 50

Today I Learned!