Writing to a collection in MongoDB Atlas with JS server code

I need to rebuild the JS (server) code to write to a DB collection in MongoDB Atlas.

Since I am encountering some problems on the way, I decided to write this post and see if someone could give me some help by having a new look at it.

First, here is how the collection looks:

_id: 6501df383452b6a687eb89c6
channelID: "ENR6318ahecz"
voiceRecordID: "6501df352839b6a687eb89c4"
timeStamp: 1694676496005

_id: 6501df783439b6a687da89ca
channelID: "ENR6318ahecz"
voiceRecordID: "6501df712219b6a687eb89c8"
timeStamp: 1691921560338

.....

I have this scheme working in TypeScript code, to access (by reading) the collection:

    const speakSchema = new Schema({
        channelID: {
            type: String,
            required: true
        },
        voiceRecordID: {
            type: String,
            required: true
        },
        timeStamp: {
            type: Number,
            required: true
        }
    })

    interface SpeakDoc extends Document {
        channelID: string
        voiceRecordID: string
        timeStamp: number
    }

    interface SpeakModel extends Model<SpeakDoc> {}

    const theModel = (models && models.Voice) ? (models.Voice as SpeakModel) :
                                            mongoose.model<SpeakDoc, SpeakModel>
                                                    ('Voice',speakSchema,'mycollection')

Then I have code like the one below to read the collection:

    await connectMDB()

    try {
        const theResult = await theModel
        .find({channelID:channel})
        return theResult
    } catch (error) {
        console.error("Error in Read-Function:", error);
        throw error; // Rethrow the error to propagate it.
    }

All the above works perfectly for now.

Next comes the problem. I need to be able to insert new records in the collection using JS. The code is in express server.

Here is what I have at this point, but it is not working:

    ....
    const {Schema,model} = mongoose;

    const vxSchema = new Schema({
      channelID: String,
      voiceRecordID: String,
      timeStamp: Number
    },
    {
        versionKey: false 
        /* This gets rid of the "__v: 0" that is
        otherwise added to the collection. */
    });

    const VxIns = model('VxIns', vxSchema);

    .....

    server.post('/upload', async (req, res) => {
        try {
            .....
            const fileId = "some-random-string";
            // Create a new blog VX object:
            const newRcd = new VxIns({
                channelID:req.body.channel,
                voiceRecordID:fileId,
                timeStamp: new Date().getTime()
            });
        
            // Insert the newRcd in our MongoDB database
            await newRcd.save();
            res.json({ fileId });
        } catch (error) {
            console.error(error);
            res.status(500).json({
                message: 'An error occurred during upload.',
                error: JSON.stringify(error)
            });
        }
    });

Can someone see at a glance what is, or what could be, wrong in this last chunk of code ? Knowing that the first presented TypeScript code is working.

How to record microphone audio from popup in a Chrome Extension?

I’m making a chrome extension where I want to record the audio from user’s microphone and then save it as a file .

Code flow :

  • Popup.js sends a message to background to : “requestMicrophonePermission”
    popup js

  • Background.js on listening for the “requestMicrophonePermission” event , executes the ContentScript.js and also triggers a “requestMicrophonePermission” event . (below is my background js)
    background js

  • ContentScript.js on listening for the “requestMicrophonePermission” event , requests the user for microphone permission and once it is granted , it triggers the “microphonePermissionGranted” event with payload of ‘stream’ , ‘streamId’ for the popup.js
    content script

  • Popup.js on listening for the “microphonePermissionGranted” event should perform the startRecording() function and other subsequent functions .
    popup js

Note : I’m able to generate the popup that asks for the mic-permission and hence passing the stream to the popup.js from contentScript , but the on passing the same ‘stream’ to the ‘startRecording()’ the following error is seen on the browser console:

error message

  • My ‘stream’ object looks like : stream object

As a solution , I tried to get the stream from the streamId received from contentScript , below is my popup.js
popupjs

  • It didn’t work as well , here is what I received : enter image description here

show the installation PWA Prompt without user iteraction

I tried to show the user the PWA Prompt installation message after the website page loaded.
I know that it works using a button, but we want to improve our installation conversion by showing the installation prompt after the site is loaded.

for example, with this code, I get an error of “The prompt() method must be called with a user gesture”:



//install from button
window.addEventListener('beforeinstallprompt', (e) => {
    // Prevent Chrome 67 and earlier from automatically showing the prompt
    e.preventDefault();
    // Stash the event so it can be triggered later.
    this.deferredPrompt = e;

    console.log('beforeinstallprompt!');
    // if askedOnce is true, no need to ask again.
    this.showPwaPrompt = !this.askedOnce;
  });


function acceptPwaPrompt() {
  this.showPwaPrompt = false;
  this.askedOnce = true;
  this.deferredPrompt.prompt();  // Wait for the user to respond to the prompt
  this.deferredPrompt.userChoice.then((choiceResult) => {
    if (choiceResult.outcome === 'accepted') {
      console.log('User accepted the A2HS prompt');
    } else {
      console.log('User dismissed the A2HS prompt');
    }

    this.deferredPrompt = null;
  });
}

setTimeout(() => { acceptPwaPrompt();}, 2000)


HTML: How to apply a specific style to the last pressed button in a div

I have a div which contains several buttons. I would like for only the button that was pressed last to have a different style, to indicate that it was button that has been most recently pressed. Clicking elsewhere on the page or on another page should not affect the buttons in the div.

For example:
There are two styles in CSS for the button: unselected and selected. All buttons have the unselected style when the page loads. If I press button 1, it should change to the selected style. If I then press button 2, button 1 will revert back to the unselected style, and button 2 will change to the selected style.

I’ve tried using the active parameter for the buttons, but the button loses active status if I click on another page.

Fetching data to React app with setInterval function

im trying to fetch data to my react app. What is the best solution to fetch data every second? I have it in setInterval, which is probably not the best 🙂 Because of it, if the requests are still pending, because of slow connection for example, then I have like tens of pending requests in network in dev tools. Here is my code.

    const [dataRigs, setDataRigs] = useState<[]>([]);
    const [dataGames, setDataGames] = useState<[]>([]);
    const [dataMeta, setDataMeta] = useState<MetaType>({});

    const getStaticData = async () => {
        const metadata = await fetch(process.env.REACT_APP_API_URL + '/Enumerations/venue-metadata');
        const metaJson = await metadata.json();

        setDataMeta(metaJson);
    }

    const getRefreshedData = async () => {
        const rigs = await fetch(process.env.REACT_APP_API_URL + '/Rigs');
        const games = await fetch(process.env.REACT_APP_API_URL + '/GroupSessions');
        const rigsJson = await rigs.json();
        const gamesJson = await games.json();

        setDataRigs(rigsJson);
        setDataGames(gamesJson);
    }

    useEffect(() => {
        getStaticData();
    }, []);

    useEffect(() => {
        let interval = setInterval(() => getRefreshedData(), (1000))

        //destroy interval on unmount
        return () => clearInterval(interval)
    }, []); `

I tried to do something like a gettingRefresh variable, which in each iteration of setInterval function, but it did not work 🙁

Why typescript doesn’t check undefined when calling specific array index

I’m trying to investigate why there is a runtime error when I called article.posts[0].title

I have post and posts and I want to call the first post of article (posts[0].title).
typescript assume I have posts size greater than 0 and doesn’t throw any error.

type Post = {
    title: string
    url: string
}

type Posts = Maybe<Array<Post>>

type Article = {
   posts: Posts
}

and global type

type Maybe<T> = T | null;

is there a typescript rule, eslint plugin or editor plugin that can detect this issue?

const article: Article = {
    posts: [],
}

article.posts?.[0].url

the final and correct code should be

const article: Article = {
    posts: [],
}

article.posts?.[0]?.url

thank you in advance.

error image

Hashing and HMAC gives different output in Python and JS

I am trying to convert a python code That encode a string With HMAC into JS using Crypto JS. But the HMAC string produced in the python and JS COde is different.

Python code

`

import hashlib, json, hmac, secrets

date = "2024-01-16 16:11:11"
nonce = 'ksjdnf5646512'
data = {key:value}
method = 'PATCH'
api = 'api'
content_type = 'application/json'
    
hashed_data = hashlib.sha256(json.dumps(data).encode('utf-8')).digest()
string_to_hash = f"{method}n{date}n{api}n{content_type}n{nonce}n{hashed_data}"
hmac_string = str(hmac.new('secretkey'.encode('utf-8'), string_to_hash.encode('utf-8'), hashlib.sha256).hexdigest())

print(json.dumps(data))
print(json.dumps(data).encode('utf-8'))
print(hashlib.sha256(json.dumps(data).encode('utf-8')))
print(string_to_hash)
print(hashed_data)
print(hmac_string)

JS Code

var CryptoJS = require("crypto-js");
date = "2024-01-16 16:11:11"
nonce = 'ksjdnf5646512'
data = {key: value}
method = 'PATCH'
api = 'api'
content_type = 'application/json'
data = JSON.stringify(data)
hashed_data = CryptoJS.SHA256(CryptoJS.enc.Latin1.parse(data))
const string_to_hash = `${method}n${date}n${api}n${content_type}n${nonce}n${hashed_data}`;
const hmacString = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(CryptoJS.enc.Latin1.parse(string_to_hash), CryptoJS.enc.Latin1.parse('secretkey')))
console.log(hmacString)

The HMAC string produced in both codes are different.

I tried using different encryptions in Crypto JS. I cannot chenge the python code. I can write the JS code as i want. I thik the issue might be due to difference in libraries in python and js

Is execution of main thread javascript code a macro-task?

I was reading this blog about event loop and micro/macrotask queues in javascript but I have doubts about the statements from the blog:

In JavaScript, no code is allowed to execute until an event has occurred. It is worth mentioning that the execution of a JavaScript code execution is itself a macro-task.

Macro-tasks include parsing HTML, generating DOM, executing main thread JavaScript code, and other events such as page loading, input, network events, timer events, etc. Examples: setTimeout, setInterval, setImmediate,requestAnimationFrame, I/O, UI Rendering.

What I know is that execution of the javascript code can’t be macro-task unless it is user interaction like a click, setTimeout etc.

I don’t get this beacause all I know is that macrotasks and microtask are generally asynchronous operations and execution of main thread javascript code is synchronous codes like console.log("hello") . Correct me please if I am mistaken.

CSS: element that only visible above certain elements

Is it possibe by any way to make element that only can be visible above certain other elements?

For example, in this code, I would like the .reflection element to be visible only above the .reflective elements (which are at the top and bottom) and not visible on the .non-reflective element (which is in the center):

  .bg
  {
      position: relative;
      width: 300px;
      height: 150px;
      background-color: green;
  }
  .reflective
  {
      width: 100%;
      background-image: url(https://sample.wdd.co.il/wp-content/uploads/sites/6/2024/01/mahogany-4.jpg);
      height: 45px;
      margin: 2.5px 0;
      border: 1px solid gray;
      border-radius: 15px;
      box-shadow: inset 0 0 10px black;
  }
  .non-reflective
  {
      width: 100%;
      background-color: transparent;
      height: 50px;
      border: 1px solid brown;
      border-radius: 15px;
  }
  .reflection
  {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
      width: 250px;
      height: 150px;
      border-radius: 100%;
      background: linear-gradient(to bottom right, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%);
  }
<div class="bg">
    <div class="reflective"></div>
    <div class="non-reflective"></div>
    <div class="reflective"></div>
    <div class="reflection"></div>
</div>

Select partial text within a table cell, when I click a button

There is a paragraph of text inside a element in a table. For instance, the below paragraph.

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

When I click a button, I want part of the text highlighted – for instance, the starting of the second sentence -> “It has survived not only”.

I tried using the setSelectionRange() function. But that works only on and elements. Are there any other similar functions that I can use for text content inside a element?

How to close bootstrap 5 modal with react

I am using bootstrap 5 with react in my project. I did not install it but using cdn links to use bootstrap element in the dom. I am using bootstrap modal to update data. After the update I want to close the modal. I tried to use useRef hook but it does not work and it is giving error. I tried to close it by document by id but still its not wroking. My code is

<div
          className="modal fade"
          id="QuestEditModal"
          tabIndex="-1"
          aria-hidden="true"
        >
          <div className="modal-dialog modal-lg modal-dialog-centered">
            <div className="modal-content">
              <div className="modal-header">
                <h5 className="modal-title">Edit Question</h5>
                <button
                  type="button"
                  className="btn-close"
                  data-bs-dismiss="modal"
                  aria-label="Close"
                ></button>
              </div>

              <div className="modal-body">
                <div className="d-flex flex-row bd-highlight mb-3">
                  <div className="p-2 w-80 bd-highlight">
                    
                    <div className="input-group mb-3">
                    <label htmlFor="Question" className="form-label">Question</label>
                        <textarea className="form-control" 
                        id="Question" rows="3" cols="160" name="question"
                        value={qcont}
                        onChange={(event) => handleQChange(event)}
                        ></textarea>
                    </div>
                    <div className="input-group mb-3">
                    <button
                    type="button"
                    className="btn btn-primary float-start"
                      onClick={(e) => handleSave(e)}>
                          Update
                    </button>
                    </div>
                  </div>
                  
                </div>
              
            </div>
          </div>
        </div>
      </div>

const handleSave = (event) => {
    fetch("http://localhost:57030/api/question", {
         method: "PUT",
         headers: {
           Accept: "application/json",
           "Content-Type": "application/json",
         },
         body: JSON.stringify({
           QuestId:qid,
           ExamUid:exuid,
           QuestUid:quid,
           Content:qcont
         }),
       })
         .then(res => res.json())
         .then(res => {
             console.log(res);
             refreshList();
           },
           (error) => {
             alert("Failed" + error);
           }
         ); 
  }

Tailwindcss only working partially in React — Working in App.js but not in components

tailwindcss is only working in App.js? and not in components

i did

npm create react-app name
npm install -D tailwindcss
npx tailwindcss init
npm start

./tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{html,js}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

./index.css:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

i have also tried

@tailwind base;
@tailwind components;
@tailwind utilities;

./src/App.js:

import Navbar from './components/Navbar';

function App() {
  return (
    <div>
      <h2 className="font-bold">Works</h2>
      <Navbar/>
    </div>
  );
}

export default App;

./src/components/Navbar.jsx:

const Navbar = () => {
  return (
    <div className="bg-slate-800">
        <h1 className="text-2xl">hello</h1>
        
    </div>
  )
}

export default Navbar

the output on localhost

please help me. i dont understand why its not working 🙁

Why is render_template is not working twice when updating the same parameters?

I recently started using Flask, MongoDB and ElasticSearch. My MongoDB is working well and also my ElasticSearch.

The issue is that I generate a list of dictionnaries and then display the information on my HTML website. The first time I call render_template, everything is working well. Then, I modulate the inputs (with javascript). It calls my flask function (when there is a change on one of the input) for the same webpage but this time the list is different. Then, I ask to render_template the same webpage with the new list and it never displays the new one.

Here is the HTML code :

    <div class="porsche-models-gallery">
        {% for model in porsche_models %}
            <div class="porsche-model-card">
                <img src="{{ model.image_url }}" alt="{{ model.porsche_name }}" class="porsche-model-image">
                <h3 class="porsche-model-name">{{ model.porsche_name }}</h3>
                <p class="porsche-model-price">{{ model.porsche_price }} €</p>
            </div>
        {% endfor %}
    </div>

Here is the python function :

@app.route('/', methods=['GET', 'POST'])
def home():
    porsche_models_list = []

    if request.method == 'POST':
        filter_params = {
            "min_price": int(request.form.get('price-min')),
            "max_price": int(request.form.get('price-max')),
            "min_speed": int(request.form.get('speed-min')),
            "max_speed": int(request.form.get('speed-max')),
            "min_accel": float(request.form.get('accel-min')),
            "max_accel": float(request.form.get('accel-max')),
            "min_l_100": float(request.form.get('l-100-min')),
            "max_l_100": float(request.form.get('l-100-max')),
            "min_power": int(request.form.get('power-min')),
            "max_power": int(request.form.get('power-max'))
        }

        porsche_models_list = search_porsche_model('porsches', **filter_params)
    else:
        porsche_models_infos = list(get_mongodb_data(collection))

        for porsche_model_info in porsche_models_infos:
            model_data = {
                'porsche_price': porsche_model_info.get('porsche_price'),
                'porsche_name': porsche_model_info.get('porsche_name'),
                'image_url': porsche_model_info.get('image_url')
            }
            porsche_models_list.append(model_data)

    return render_template('index.html', porsche_models=porsche_models_list)

As I do not change the parameter and return the same output (with the new list), I expected to display the new set of documents instead of the last one. Do you have any idea on how to fix this?

As I really want to use ElasticSearch to fully understand it, I kept this part of the code. Then I tried to retrieve the data from my python code in the javascript without calling render_template. Then I would try to display it dynamically. Of course it does not work.

I am running out of ideas, and I am wondering why it does not work. It should (according to my understanding) just render the same webpage with a new list to display isn’t it?

making custom popover bottom position fixed and let it stretch towards top

I am making custom popover similar to a bootstrap popover, I able to make popovers in all the directions but in the top direction I am facing challenges as i want my popover to fixed is bottom just above the popover opening button and when its content increases its height increase towards top while keeping bottom fixed.

let popoverBtn = document.querySelectorAll("[data-toggle='popover']");
let popover = document.querySelector(".popover-overlay");
let popoverHeading = document.querySelector(".popover-overlay-heading h4");
let popoverContent = document.querySelector(".popover-overlay-content p");
for (let i = 0; i < popoverBtn.length; i++) {
  if (popoverBtn[i]) {
    popoverBtn[i].addEventListener("click", function(e) {
      let top = e.target.offsetTop;
      let left = e.target.offsetLeft;
      let width = e.target.offsetWidth;
      let height = e.target.offsetHeight;
      let heading = e.target.getAttribute("title");
      let description = e.target.getAttribute("data-content");
      let popoverHeight = parseFloat(getComputedStyle(popover).height);
      let popoverWidth = parseFloat(getComputedStyle(popover).width);
      let dir = e.target.getAttribute("data-placement");
      popoverHeading.textContent = heading;
      popoverContent.textContent = description;
      popover.classList.add("active");
      popover.style.top = '0px';
      popover.style.left = '0px'

      switch (dir) {
        case "top":
          popover.style.top = top - popoverHeight - 20 + "px";
          popover.style.left = left + "px";
          popover.style.bottom = top;
          break;
        case "bottom":
          popover.style.top = top + height + 5 + "px";
          popover.style.left = left + "px";
          break;
        case "left":
          popover.style.top = top + "px";
          popover.style.left = left - popoverWidth - 20 + "px";
          break;
        case "right":
          popover.style.top = top + "px";
          popover.style.left = left + width + 30 + "px";
          break;
        default:
          popover.style.top = top + "px";
          popover.style.left = left + width + 30 + "px";
          break;
      }



    })
  }
}
body {
  margin: 0px;
  padding: 0px;
  font-family: sans-serif;
}

h3,
h4,
p {
  margin: 0px;
}

.container {
  width: 100%;
}

.bg-gray {
  background-color: rgba(0, 0, 0, 0.3);
}

.bg-light-gray {
  background-color: rgba(0, 0, 0, 0.1);
}

section {
  min-height: 400px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
}

section button {
  display: inline-block;
  border: none;
  background-color: #dc3545;
  color: #fff;
  padding: 0.5rem 1rem;
  font-size: 1.25rem;
  line-height: 1.5;
  border-radius: 0.3rem;
}

.popover-overlay {
  position: fixed;
  z-index: 100;
  border-radius: 5px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
  display: none;
  width: 280px;
  height: 121px;
}

.popover-overlay.active {
  display: block;
}

.popover-overlay-heading {
  background-color: #f7f7f7;
  border-bottom: 1px solid #d3d3d3;
  padding: 1rem;
}

.popover-overlay-content {
  background-color: #fff;
  padding: 1rem;
}
<div class="popover-overlay">
  <div class="popover-overlay-heading">
    <h4></h4>
  </div>
  <div class="popover-overlay-content">
    <p></p>
  </div>
</div>
<div class="container">
  <section class="bg-gray">
    <button data-placement="top" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="It's very engaging. Right? And here's some amazing content. It's very engaging. It's very engaging. Right? And here's some amazing content. It's very engaging.">Popover Top</button>
    <button data-placement="left" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Left</button>
    <button data-placement="right" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Right</button>
    <button data-placement="bottom" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Bottom</button>
  </section>
</div>