My site is deployed on Render but I am having issues with my server/database calls once deployed

This is my first time deploying a full-stack application and I am not sure how to fix this issue.

I have deployed my app on Render and it is deploying successfully for the client side. It is the server side I am having issues with. In my local machine environment I was making server calls like this

helper function:

import axios from 'axios';
const usersRoute = process.env.REACT_APP_SERVER + ":" + process.env.REACT_APP_SERVER_PORT + "/users";


export default async function getAllUsers() {
  const { data } = await axios.get(usersRoute);
  // setData(data);
  // console.log('users data:', data);
      // setUsers(data);
      // return usersList;
      return data;

};

environment variables:

REACT_APP_SERVER=http://localhost
REACT_APP_SERVER_PORT=8000

server file:

// Get all users
app.get("/users", (req, res) => {
  db.query("SELECT * FROM users", (error, results) => {
    if (error) {
      throw error;
    }
    res.status(200).send(results.rows);
  });
});

This works in my local machine environment of course, but when I put it all into Render, it was still making the calls to my local environment, so it’s only working on my computer. I am not sure how to exactly fix it.

In my localhost environment, the client side is running on “localhost:3000/” and the server was running on “localhost:8000/”

I have tried changing it so it is just using /plants as the path, which failed when put together with the deployed application URL, I have tried different variables, and seeing if I could get it to run off of the main URL in my localhost environment but that also failed.

I am just really turned around and confused right now, so any help would be appreciated.

How to sync arrays in Angular Drag-Drop Component?

I have a drag and drop component that html looks like:

 <div
    class="example-container flex flex-col text-center h-fit min-h-[10rem] w-[15%] border-2 border-gray-100 rounded-md shadow-md"
  >
    <h2
      class="text-xl font-semibold mx-auto py-4 bg-green-100 w-full drop-shadow-md"
    >
      Monday
    </h2>
    <div
      cdkDropList
      [cdkDropListData]="Monday"
      class="example-list bg-red-100 min-h-[5rem]"
      (cdkDropListDropped)="drop($event)"
    >
      @for (item of Monday; track item) {

      <app-drag-drop-item [title]="item" cdkDrag></app-drag-drop-item>
      }
    </div>
  </div>

and second container:

<div
    class="example-container flex flex-col text-center h-fit min-h-[10rem] w-[15%] border-2 border-gray-100 rounded-md shadow-md"
  >
    <h2
      class="text-xl font-semibold mx-auto py-4 bg-blue-100 w-full drop-shadow-md"
    >
      Tuesday
    </h2>
    <div
      cdkDropList
      [cdkDropListData]="Tuesday"
      class="example-list bg-red-100 min-h-[5rem]"
      (cdkDropListDropped)="drop($event)"
    >
      @for (item of Tuesday; track item) {

      <app-drag-drop-item [title]="item" cdkDrag></app-drag-drop-item>
      }
    </div>
  </div>

I have two days and taks for each day, that are stored in an array:

  Monday = ['Refractoring'];
  Tuesday = ['Gym'];

And i can using Angular CDK Drap and drop:

https://material.angular.io/cdk/drag-drop/overview

move this tasks on the screen.
The problem is that the changes doesnt reflect the actuall array.
So if a have two arrays:

  Monday = ['Refractoring'];
  Tuesday = ['Gym'];

and then i move taks from Monday on Tuesday, the arrays element didnt change. althoug on the screen i have to tasks in Tuesady Conatainer.

the component.ts file

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import {
  CdkDragDrop,
  CdkDrag,
  CdkDropList,
  CdkDropListGroup,
  moveItemInArray,
  transferArrayItem,
} from '@angular/cdk/drag-drop';
import { DragDropItemComponent } from '../drag-drop-item/drag-drop-item.component';
import { MatIconModule } from '@angular/material/icon';
import { FormsModule } from '@angular/forms';
import { AddTaskFormComponent } from '../add-task-form/add-task-form.component';
import { TaskService } from '../../../../shared/services/task.service';

@Component({
  selector: 'app-dashboard-space',
  standalone: true,
  imports: [
    CdkDropListGroup,
    CdkDropList,
    CdkDrag,
    DragDropItemComponent,
    DragDropItemComponent,
    MatIconModule,
    FormsModule,
    AddTaskFormComponent,
    CommonModule,
  ],
  templateUrl: './dashboard-space.component.html',
  styleUrl: './dashboard-space.component.css',
})
export class DashboardSpaceComponent {
  constructor(private e: TaskService) {
    this.tasks = this.e.getTasks();
  }

  tasks: any[];

  todo = ['Get to work', 'Pick up groceries', 'Go home', 'Fall asleep'];

  Monday = ['Refractoring'];
  Tuesday = ['Gym'];
  Wednesday = ['Interview'];
  Thursday = ['TV'];
  Friday = ['Sport'];

  done = ['Get up', 'Brush teeth', 'Take a shower', 'Check e-mail', 'Walk dog'];

  newTask: string = '';

  addNewTask() {
    this.todo.push(this.newTask);
  }

  handleFormSubmission(formData: any) {
    this.todo.push(formData);
  }

  drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex,
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex,
      );
    }
  }
}

I follow arrays with:

  <h1>{{ Monday }}</h1>
  <h1>{{ Tuesday }}</h1>

How to sync it drag and drop with actuall arrays that are coded?

The request works using cURL, but doesn’t work in Postman and browser

Node Js (express) server responds to requests via cUrl, but gives infinite load when requested via Postman or browser. There are no errors
Found similar tracks, but none of them helped me.
Can you tell me what this might be related to?

Express js

const app = express();
app.use(cors());
app.use(express.json());
app.use(express.static(path.resolve(__dirname, 'static')))
app.use(fileUpload({}))
app.use('/api', router)

app.use(errorHandler)

const start = async () => {
    try {
        await sequelize.authenticate();
        await sequelize.sync();
        app.listen(PORT, () => {
            console.log(`Server started on port ${PORT}`);
        });
    } catch (e) {
        console.log(e);
    }
};

start();

Following advice from other posts, tried changing the Postman settings, but nothing helped.

What is the best way for me to compose my regex?

/(w+)(((?:(?:[^)("]|\(|\\)*?)|(?:"(?:[^"\]|\\|\")*?"))))(?<!) )(?:.(w+)(((?:(?:[^)("]|\(|\\)*?)|(?:"(?:[^"\]|\\|\")*?"))))?/

This regex highlights the function call in my compiler. The thing is, I have two lines:

_comm => (name) string("g").set(g);
s(а).get();

Regex (according to regex101) highlights all function calls and cuts them into the groups I need, but the string capture itself… I need that if function is preceded by ) (closed bracket and space), it should not match it in any way, at all. But, I don’t know how to do it

By the way, the strings that the regex should cover should be like this:

s(а).get()

Because the string("g").set(g) is preceded by () (which is a closed parenthesis with a space)

I’ve already searched the internet and AI and nothing has given any results

disconnecting all members from channel discord.js v14

    try {

    const {guild} = interaction

    const channel = interaction.options.getChannel('channel');

    const channelId = interaction.options.getChannel('channel').id;

    const member2kick = []
    
    member2kick.push(guild?.members.cache.filter(member => member.voice.channelId === channelId).firstKey() as string);

    console.log(member2kick);

    if (channel.type !== ChannelType.GuildVoice) return await interaction.reply({
        embeds: [new EmbedBuilder().setTitle("Błąd").setDescription("Wybrany kanał nie jest kanałem głosowym.").setColor("Red")],
        ephemeral: true,
    });

    member2kick.forEach(member => {
        member.disconnect(channelId);
    });


    await interaction.reply({
        embeds: [new EmbedBuilder().setTitle("Sukces").setDescription("Pomyślnie rozłączono wszystkich użytkowników z kanału głosowego.").setColor("Green")],
        ephemeral: true,
    });

} catch (error) {
    console.error(error);
}

I just want to kick everybody from member2kick array. It’s correctly getting members from channel but I cannot find way to kick them out

Does javascript have more than one `undefined`?

in a node repl or browser console:

> ({})?.a
undefined
> (null)?.a
undefined
> (null)?.a.b
undefined
> ({})?.a.b
Uncaught TypeError: Cannot read properties of undefined (reading 'b')

if (anything)?.a is undefined then why does the undefined that’s returned by (null)?.a NOT throw an error when I read its non-existent properties?

Multiple linear regression in Javascript. Is tensorflow.js really the only/best option?

It seems like neither regression.js nor simple-statistics.js support multiple linear regressions featuring 2+ independent variables. However, with tensorflow.js, it does seem possible to achieve building a multiple linear regression with a model that looks something like this:

import * as tf from '@tensorflow/tfjs';

// Sample data: let's assume X1, X2 are independent variables and Y is the dependent variable.
const X1 = [1, 2, 3, 4];
const X2 = [2, 2, 4, 3];
const Y = [2, 4, 6, 8];

// Convert data to tensors
const xs = tf.tensor2d([X1, X2], [4, 2]); // Shape is [num_samples, num_features]
const ys = tf.tensor1d(Y);

// Build a model
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [2]})); // inputShape is 2 because we have 2 independent variables

// Compile the model
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});

// Train the model
(async () => {
  await model.fit(xs, ys, { epochs: 100 });
  model.predict(tf.tensor2d([[5, 5], [6, 7]], [2, 2])).print(); // Predicting for new data
})();

Am I missing something with regards to the first two libraries not supporting multiple linear regressions? Pulling our tensorflow.js seems overkill for this, but also seems like it may be the only option here (outside of doing our own matrix math using mathjs). Anyone else have experience model fitting multiple linear regression in javascript?

onmouseover not triggering but onmouseleave works just fine

I’ve been having problems with onmouseover function, basically theres a div in another div that’s in display:none and when hovered it becomes display: block

<div class="container"
    <div class="menu-item">
        <div class="header"><p>My Neighbor Totoro</p></div>
        <div class="body" id="card4" onclick="showHiddenDiv()">
            <div class="showDiv" id="preview" onmouseover="showDivRevert(event)" onmouseleave="showDivRevert(event)">Action, Comedy, Drama</div>
        </div>
   </div>
</div>


.showDiv{
    position: relative;
    bottom: -429px;
    padding: 20px;
    background-color: white;
    width: 100%;
    font-family: 'Poppins';
    text-align: center;
    font-size: 15px;
    opacity: 0.8;
    -webkit-transition: all .5s ease-in-out;
    -moz-transition: all .5s ease-in-out;
    transition: all .5s ease-in-out;
    display: none;
}

.menu-item {
    display: flex;
    flex-direction: column;
    border: 1px solid black;
    width: 100%; 
    height: 550px;
    border-radius: 25px;
}

.header {
    height: 50px; 
    padding: 10px;
    text-align: center;
    background-color: #6FA66F;
    box-shadow: rgba(0, 0, 0, 0.17) 0px -23px 25px 0px inset, rgba(0, 0, 0, 0.15) 0px -36px 30px 0px inset, rgba(0, 0, 0, 0.1) 0px -79px 40px 0px inset, rgba(0, 0, 0, 0.06) 0px 2px 1px, rgba(0, 0, 0, 0.09) 0px 4px 2px, rgba(0, 0, 0, 0.09) 0px 8px 4px, rgba(0, 0, 0, 0.09) 0px 16px 8px, rgba(0, 0, 0, 0.09) 0px 32px 16px;
    border-radius: 10px;
}

.body{
    flex: 1; 
    padding: 0px;
    height: 300px;
    box-shadow: rgba(0, 0, 0, 0.17) 0px -23px 25px 0px inset, rgba(0, 0, 0, 0.15) 0px -36px 30px 0px inset, rgba(0, 0, 0, 0.1) 0px -79px 40px 0px inset, rgba(0, 0, 0, 0.06) 0px 2px 1px, rgba(0, 0, 0, 0.09) 0px 4px 2px, rgba(0, 0, 0, 0.09) 0px 8px 4px, rgba(0, 0, 0, 0.09) 0px 16px 8px, rgba(0, 0, 0, 0.09) 0px 32px 16px;
    border-radius: 10px;
}

.container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px; 
    width: 80vw; 
    height: auto; 
}

I tried using position absolute, using an id instead of class, using the z-index instead, using an id, using onclick=”showHiddenDiv(this)”, then not using an inline onmouseover:

function showDivChange(event) {
      element = document.getElementById('preview');
      element.addEventListener("mouseover",function(){
        this.style.display = "block";
      });
    }

    function showDivRevert(event) {
      const element = event.target;
      event.stopPropagation();
      element.style.display = "none";
    }

which is confusing since I tried setting the showDiv to display: block to try the onmouseleave and it works just fine. Any help is appreciated, Thank you!

I want to add two functions to a button, but only one function runs

The two functions work fine separately, but when I try to run them together using onclick in the HTML or AddEventListner or by creating a combined function of the two function, only the calculate function works.

How do I make the genbutton function also work when calculate is clicked?

const generatebutton = document.getElementById("explainbutton");


const wt = document.getElementById("b2");
const ht = document.getElementById("b3");
const bmi = document.getElementById("b5");
 const calc = document.getElementById("b7");
const clr = document.getElementById("b8");

// // calculate bmi funtion
function calculate() {
  console.log(`running calculate`);
  const wt = document.getElementById("b2").value;
  const ht = document.getElementById("b3").value;
  const solve = Number.parseFloat(wt / ht ** 2).toFixed(2);
  document.getElementById("b5").textContent = solve;
};

// function make explain button appear 

function genbutton () {
  console.log(`running genbutton`);
  generatebutton.style.visibility = "visible";
};

//activate both functions in one click
calc.addEventListener("click", function(){
     calculate();
     genbutton();
});
#explainbutton {
  visibility: hidden;
  margin-left: 190px;
}
<div id="b1">
  <span id="sp1">
    WEIGHT(kg) :
  </span>
  <input type="number" id="b2">
  </input>
</div>
<br>
<div id="b9">
  <span id="sp2">
    HEIGHT(m) :
  </span>
  <input type="number" id="b3">
  </input>
</div>
<br>

<div id="bmibox">
  BMI :
  <span id="b5" </span>
    <INPUT TYPE="BUTTON" VALUE="What does this mean?" class="styled-button-2" id="explainbutton"> </b>
    

</div>

<br>
<br>
<div id="b6">
  <INPUT TYPE="BUTTON" VALUE="Calculate" class="styled-button-2" id="b7">
  <button id="b8">Clear</button>
</div>

How to drag and drop image on another image

I want to drag an image and drop it on another image. When I try to drop an image on the other the dragged image disappears. After dropping the image I want the image behind it to disappear(i.e. not the dragged image). But whenever I try to do this, the dragged image is disappearing. Any suggestions?

Here’s the code which I tried code:
HTML

<!DOCTYPE HTML>
<html>

<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="assignment_5_css.css">
    <title>Assignment 5</title>
</head>

<body>
    <!--<div class="gfg">DRAG AND DROP</div>
    <p>Image Drag and Drop in boxes</p>-->
    <br>
    <br>
    <div class="row1">
        <div class="d1">
        </div>
    
        <div class="div1 used-boxes"
            ondrop="dragDrop(event)"
            ondragover="allowDrop(event)"> 
            
            <img id="drag1" class="img"
                src="C:UsersUsernameDocumentsimage.png"
                draggable="true"
                ondragstart="dragStart(event)">
        </div>
        
        <div class="d2"></div>
    </div>
    <br>
    <br>
    <div class="row1">
        <div class="d3 used-boxes"
            ondrop="dragDrop(event)"
            ondragover="allowDrop(event)"> 
        </div>
        
        <div class="d7 used-boxes"
            ondrop="dragDrop(event)"
            ondragover="allowDrop(event)">
            
            <img id="drag2" class="img"
                src="C:UsersUsernameDownloadsimage.jpg"
                draggable="true"
                ondragstart="dragStart(event)">
        </div>
        
        <div class="d4 used-boxes"
            ondrop="dragDrop(event)"
            ondragover="allowDrop(event)"></div>
    </div>
    <br>
    <br>
    <div class="row1">
        <div class="d5"> 
        </div>
        
        <div class="d8 used-boxes"
            ondrop="dragDrop(event)"
            ondragover="allowDrop(event)">
        </div>
        
        <div class="d6"></div>
    </div>
    
    <script src="assignment_5_javascript.js"></script>
</body>

</html>

CSS

.div1 {
    position: absolute;
    left: 300px;
    width: 250px;
    height: 250px;
    padding: 10px;
    border: 5px solid #2C74B3;
    border-radius: 25px;
}

p {
    font-size: 20px;
    font-weight: bold;
}

.gfg {
    font-size: 35px;
    color: #F08A5D;
    font-weight: bold;
}

.img {
    width: 250;
    height: 250;
    border-radius: 25px;
}

.row1 {
    position: relative;
    width: 750px;
    height: 250px;
}

.d1 {
    position: absolute;
    left: 20px;
    width: 250px;
    height: 250px;
    padding: 10px;
    /*background-color: #2B2E4A;*/
}

.d2 {
    position: absolute;
    left: 582px;
    width: 250px;
    height: 250px;
    padding: 10px;
    /*background-color: #2B2E4A;*/
}

.d3 {
    position: absolute;
    left: 20px;
    width: 250px;
    height: 250px;
    padding: 10px;
    border: 5px solid #2C74B3;
    border-radius: 25px;
    /*background-color: #2B2E4A;*/
}

.d4 {
    position: absolute;
    left: 582px;
    width: 250px;
    height: 250px;
    padding: 10px;
    border: 5px solid #2C74B3;
    border-radius: 25px;
    /*background-color: #2B2E4A;*/
}

.d5 {
    position: absolute;
    left: 20px;
    width: 250px;
    height: 250px;
    padding: 10px;
    /*background-color: #2B2E4A;*/
}

.d6 {
    position: absolute;
    left: 582px;
    width: 250px;
    height: 250px;
    padding: 10px;
    /*background-color: #2B2E4A;*/
}

.d7 {
    position: absolute;
    left: 300px;
    width: 250px;
    height: 250px;
    padding: 10px;
}

.d8 {
    position: absolute;
    left: 300px;
    width: 250px;
    height: 250px;
    padding: 10px;
    border: 5px solid #2C74B3;
    border-radius: 25px;
}

Javascript

function allowDrop(ev) {
        ev.preventDefault();
    }

    function dragStart(ev) {
        ev.dataTransfer.setData("text", ev.target.id);
    }

    function dragDrop(ev) {
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        ev.target.appendChild(document.getElementById(data));
    }

Cannot drag items into empty columns dnd-kit

I’m using dnd kit for my reactJS app and I’m only able to drag and drop items into columns that have at least 1 item already inside it. If a column is empty, I cannot drag items into it. I know that it has to be the way I implemented my handleDragEnd function inside my board.jsx file.

Here is the code for reference: https://codesandbox.io/p/sandbox/dnd-kit-learning-v78dpc

Each time I change the logic in my handleDragEnd function, I either ruin the auto sorting that it has when an item is placed in a different position of its original column, items no longer being draggable, or my original problem above. I’ve tried many different ways to alter my logic, but I still get the same wrong result. Can someone see what I’m doing wrong?

Angular named router outlet link does not

While using router outlets in Angular I’m facing some problems.

I want to have a link like “maintopic/subtopicHeadline/subtopic”, where I set the routes like this:

export const routes: Routes = [
  { path: 'home', component: AppComponent },

  {
    path: ':maintopic',
    component: SidenavMainComponent
  },
 
  {
    path: ':subtopicHeadline/:subtopic',
    component: ContentHandlerComponent,
    outlet: 'content'
  },
];

I get the values for the subtopicheadline and the subtopic correctly, but I don’t know how to set the link for the router outlet. For now it is [routerLink]="['',{outlets:{content:[subtopic]}}]" but there I only get a link like “/subtopic”. How must the link be written to reach the desired format?

Why am I receiving so many socket emits on my client-side?

I have a socket.io, express, node server side and a React frontend. When the final player joins a room, a function in my server triggers and shuffles seats and sends the seat list to everyone in the room. However, when I check my front-end console, the console log that’s in the socket.on listener for this seat list is triggered 16 times for the first player, 14 times for the second player, 12 for the third, … , and 6 times for the 6th and final player. The one important thing I can think of is that “seats” is already sent to the users one by one before being fully shuffled as they join the lobby.

server/index.js:

// upon join
io.to(roomCode).emit("player_joined_lobby", { seats: game.getSeats() });

server/game.js:

if (curNumPlayers >= cap) { // cap = 6
    this.randomizeSeatAndTeam();
    const seats = this.getSeats();
    const cap = this.getCapacity();

    var coveredSeats = JSON.parse(JSON.stringify(seats)); ; // deep copy of seats, team will be covered
    for (let i = 0; i < cap; i++) {
      coveredSeats[i][1] = Team.Unknown;
    }

    for (let i = 0; i < cap; i++) {
      const player = this.getPlayerByUsername(seats[i][0], cap);
      if (player.getTeam() === Team.Bad) {
        io.to(player.getId()).emit("shuffled_seats", seats);
      } else {
        io.to(player.getId()).emit("shuffled_seats", coveredSeats);
      }
    }
}

So theoretically, each socket should be receiving one emit to “shuffled_seats”.

frontend/App.js:

socket.on("player_joined_lobby", (lobbyInfo) => {
    setSeats(lobbyInfo.seats);
    setGameScreen(true);
});

socket.on("shuffled_seats", (seats) => {
    console.log("received seats: ", seats) // called so much
    setSeats(seats);
    setGameStarted(true);
});

return (
    <GameScreen seats={seats} />
)

frontend/GameScreen.jsx:

return (
    <GameTable 
        seats={seats}
        numPlayers={numPlayers} 
    />
)
export default memo(GameScreen);

frontend/GameTable.jsx:

<div style={playerRow(topRowLength)}>
        {
          // this map displays up to 4 players, 3 if there are <= 6 players
          seats.map(function(seat, i) {
            const seatUsername = seat[0];
            const seatTeam = seat[1];
            
            if (i < topRowLength) {
              if (username === seatUsername) {
                console.log("seatUsername and seatTeam are: ", seatUsername, seatTeam);
                // color the username
              }
              if (gameStarted) {
                return <PlayerBox 
                          key={i}
                          teamStyle={seatTeam === "badTeam" ? badTeamStyle : {}} 
                          username={seatUsername}
                        />
              } else {
                return <PlayerBox key={i} username={seatUsername || "waiting.."}/>
              }
            } else {
              return <></>
            }
          })
        }
      </div>
    ...

export default memo(GameTable);

How to cause a window-resize event programmatically

I have an npm package that I use to render in PDF’s in React, but it renders it into a resizable column. Some parts of the PDF viewer resizes when I resize the column, but not the actual PDF view. But as soon as I resize the browser window the PDF view instantly snaps to the new width.

I

Normal view

enter image description here

Column resized… the toolbar resizes but not the scroll bar or the PDF view

enter image description here

After I slightly change window width

The PDF viewer obviously listens for an onWindowResize event, but short of trying to modify the PDF package or change my code fundamentally, is there a hook or a method that I can use to just trigger a window resize event without actually changing window size, that I can just add to the column resize event?

Whyonly my drawLine function working properly?

so I’m at the beginning of learning canvas and how to control it, and in my code the only function that’s not drawing anything on the surface of the canvas is drawLine, which is supposed to draw a dot or line if it’s triggered by onMove.
Could you please help me understand why?

The canvas service

'use strict'

let gPencil = { pos: null, isDown: false }
let gShape = ''
let gColor = ''
let gStrokeColor = ''
let gDrawings = []

function addListeners() {
    addMouseListeners()
    addTouchListeners()
    window.addEventListener('resize', () => {
        resizeCanvas()
    })
}       

function addMouseListeners() {
    gElCanvas.addEventListener('mousedown', onDown)
    gElCanvas.addEventListener('mousemove', onMove)
    gElCanvas.addEventListener('mouseup', onUp)
}

function addTouchListeners() {
    gElCanvas.addEventListener('touchstart', onDown)
    gElCanvas.addEventListener('touchmove', onMove)
    gElCanvas.addEventListener('touchend', onUp)
}

function drawShape(x, y) {
    gCtx.moveTo(x, y)
    gCtx.beginPath()

    if (gShape === '') {
        alert('You have not chosen a shape.')
        return
    }
    else if (gShape === 'squares') drawRect(x, y)
    else if (gShape === 'triangles') drawTriangle(x, y)
    else if(gShape === 'circles') drawCircle(x, y)
    else if (gShape === 'pencil') drawLine(x, y)

    gDrawings.push(gPencil.pos)
    gCtx.save()
}

function drawRect(x, y) {
    gCtx.strokeRect(x, y, 40, 40)
    gCtx.fillRect(x, y, 40, 40)
    gCtx.stroke()
}

function drawTriangle(x, y) {
    gCtx.lineTo(x + 70, y)
    gCtx.lineTo(x, y + 70)
    gCtx.closePath()
    gCtx.stroke()
    gCtx.fill()
}

function drawCircle(x, y) {
    gCtx.arc(x, y, 50, 0, 2 * Math.PI)
    gCtx.stroke()
    gCtx.fill()
}

function drawLine(x, y) {
    gCtx.lineTo(x ,y)
    gCtx.stroke()
    gCtx.fill()
}

function resizeCanvas() {
    const elContainer = document.querySelector('.canvas-container')
    gElCanvas.width = elContainer.clientWidth
}

function onDrawLine(ev) {
    if (!gPen.isDown) return
    const { offsetX, offsetY } = ev

    gPen.pos = { x: offsetX, y: offsetY }
    gLine.push(gPen.pos)
    
    gCtx.lineTo(offsetX, offsetY)
    gCtx.stroke()
}

The canvas controller

'use strict'

let gElCanvas
let gCtx

function onInit() {
    gElCanvas = document.querySelector('canvas')
    gCtx = gElCanvas.getContext('2d')
    gCtx.lineWidth = 4
    addListeners()
}

function onDown(ev) {
    ev.stopPropagation()
    const elNav = document.querySelector('.nav-bar')
    gShape = elNav.querySelector('.shapes').value
    gStrokeColor = elNav.querySelector('#stroke-color').value
    gColor = elNav.querySelector('#color').value
    gCtx.fillStyle = gColor
    gCtx.strokeStyle = gStrokeColor
    gDrawings = []

    gPencil.isDown = true

    const x = ev.offsetX
    const y = ev.offsetY

    gPencil.pos = {x, y}

    // gCtx.beginPath()
    // gCtx.moveTo(x, y)
    drawShape(x, y)
}

function onMove(ev) {
    
    ev.stopPropagation()
    if (!gPencil.isDown) return

    const { offsetX: x, offsetY: y } = ev
    gPencil.pos = { x, y }
    // gShape = document.querySelector('.nav-bar .shapes').value
    drawShape(x, y)
    gDrawings.push(gPencil.pos)
}

function onClearBtn() {
    gCtx.clearRect(0, 0, gElCanvas.width, gElCanvas.height)
}

function onUp(ev) {
    ev.stopPropagation()
    gCtx.closePath()
    gPencil.isDown = false
}

function onDownloadCanvas(elA) {
    const canvasContent = gElCanvas.toDataURL('image/jpeg')
    elA.href = canvasContent
}

function onImgInput(ev) {
    loadImageFromInput(ev, renderImg)
}

function loadImageFromInput(ev, onImageReady) {
    const reader = new FileReader()

    reader.onload = ev => {
        let img = new Image()
        img.src = ev.target.result
        img.onload = () => onImageReady(img)
    }
    reader.readAsDataURL(ev.target.files[0])
}

function renderImg(img) {
    gElCanvas.height = (img.naturalHeight / img.naturalWidth) * gElCanvas.width
    gCtx.drawImage(img, 0, 0, gElCanvas.width, gElCanvas.height)
}


function onSaveBtn() {
    gCtx.save()
}

function coverCanvasWithImg(elImg) {
    gElCanvas.height = (elImg.naturalHeight / elImg.naturalWidth) * gElCanvas.width
    gCtx.drawImage(elImg, 0, 0, gElCanvas.width, gElCanvas.height)
}

function onShareImg() {
  
    const imgDataUrl = gElCanvas.toDataURL('image/jpeg') 

    function onSuccess(uploadedImgUrl) {
        const url = encodeURIComponent(uploadedImgUrl)
        window.open(`https://www.facebook.com/sharer/sharer.php?u=${url}&t=${url}`)
    }
    
    doUploadImg(imgDataUrl, onSuccess)
}

function doUploadImg(imgDataUrl, onSuccess) {
    const formData = new FormData()
    formData.append('img', imgDataUrl)

    const XHR = new XMLHttpRequest()
    XHR.onreadystatechange = () => {
        if (XHR.readyState !== XMLHttpRequest.DONE) return
        if (XHR.status !== 200) return console.error('Error uploading image')
        const { responseText: url } = XHR
        console.log('Got back live url:', url)
        onSuccess(url)
    }
    XHR.onerror = (req, ev) => {
        console.error('Error connecting to server with request:', req, 'nGot response data:', ev)
    }
    XHR.open('POST', '//ca-upload.com/here/upload.php')
    XHR.send(formData)
}

HTML

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas Exercise</title>
    <link rel="stylesheet" href="css/style.css">
</head>

<body onload="onInit()">
    <header>
        <h1>Mister Canvas</h1>
        <nav>
            <ul class="nav-bar">
                <li><input type="color" id="stroke-color" value="#ffffff"></li>
                <li><input type="color" id="color" value="#ffffff"></li>
                <li><select class="shapes">
                    <option value="">Select a shape</option>
                    <option value="squares">Square</option>
                    <option value="circles">Circle</option>
                    <option value="triangles">Triangle</option>
                    <option value="pencil">Pencil</option>
                </select></li>
                <li><button class="nav-bar-btn" onclick="onSaveBtn()">Save</button></li>
                <li><button class="nav-bar-btn" onclick="onClearBtn()">Clean</button></li>
                <li><input type="file" onchange="onImgInput(event)" accept="image/*"></li>
                <li><a href="#" class="download-btn" onclick="onDownloadCanvas(this)" download="my-canvas.jpg">Download</a></li>
                <li><button class="share-btn" onclick="onShareImg()"> Share to Facebook </button></li>
                
            </ul>
        </nav>

    </header>
    <main>
        <div class="canvas-container">
            <canvas width="450" height="450"></canvas>
        </div>
    </main>
    <script src="js/canvas-controller.js"></script>
    <script src="js/services/canvas.service.js"></script>
    
</body>
</html>           

I have tried to debugg it and read a few times all the lines in each js file,
asked the chatGPT and one more dev community , but got no answer.