Shopware 6: backwards compatiblity of compiled JS in plugin

One of our SW6 plugins comes with fairly basic javascript code. Before shipping it to the SW plugin store, I use the bin/build-frontend.sh script to compile the js assets just as described in the documentation:

https://developer.shopware.com/docs/guides/plugins/plugins/storefront/add-custom-javascript

This has always worked without problems for me. But somewhere in the 6.4.x series, more and more customers reported incompatiblities with their Shopware version. I often have trouble reproducing the error. Most customers report this JS error:

Uncaught TypeError: Cannot read properties of undefined (reading 'call')

click to see js error

My workaround so far has been to install a demo shop with the Shopware version they are using, install my plugin, compile the JS and ship this version to them – with does not seem right at all. Is there any compatibility table or maps which lets me know if a new Shopware Version breaks bw compatiblity when I compile my JS? Or am I missing something?

Any help is very much appreciated.

What is the alternative of innerHTML to Speed Up the Webpage

I’m working on a project and for that project I have created a custom dropdown international country code selection section, and for that I have injected all the SVG flag icons using innerHTML and I have noticed that after using the 240 lines of innerHTML the performance/ loading speed of my website is being negatively affected by the innerHTML.

Please have a look on my JS Code –

I have also read many articles on the internet that innerHTML is very slow but I have not found any alternative to innerHTML, could you please guide me a little with my JS code to improve the performance of my app.

NOTE: I have also a doubt that does the flag icon SVG are the real culprit behind the slow loading of my app? because that contains 239 SVG flag icons. Maybe this SVG icons takes time to render on my webpage. If this was the real culprit can you please guide me to optimize my code for faster loading.

  // Autoclick on the parent div to hide the Dropdown after loading a page (Bug)
  window.addEventListener('load', () => {
      document.querySelector(".country-code-selector").click();
  });

  document.addEventListener('DOMContentLoaded', () => {

      const head = document.getElementsByTagName('head')[0];
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.type = 'text/css';
      link.href = 'https://amitdutta.co.in/flag/css/flag-icon.css';
      head.appendChild(link);

      // Get dropdowns and form
      const dropdowns = document.querySelectorAll('[cc-data-dropdown]');
      const form = document.querySelector('.country-code-selector form');

      // Check if dropdowns exist on page
      if (dropdowns.length > 0) {
          // Loop through dropdowns and create custom dropdown for each select element
          dropdowns.forEach(dropdown => {
              createCustomDropdown(dropdown);
          });
      }

      // Check if form element exist on page
      if (form !== null) {
          // When form is submitted console log the value of the select field
          form.addEventListener('submit', (e) => {
              e.preventDefault();
              console.log('Selected country:', form.querySelector('[name="country"]').value);
          });
      }

      // Create custom dropdown
      function createCustomDropdown(dropdown) {
          // Get all options and convert them from nodelist to array
          const options = dropdown.querySelectorAll('option');
          const optionsArr = Array.prototype.slice.call(options);

          optionsArr[0].innerHTML = '<span class="flag-icon flag-icon-afg"></span> Afganistan (+69)';
          optionsArr[1].innerHTML = '<span class="flag-icon flag-icon-alb"></span> Albania (+355)';
          optionsArr[2].innerHTML = '<span class="flag-icon flag-icon-dza"></span> Algeria (+213)';
          optionsArr[3].innerHTML = '<span class="flag-icon flag-icon-asm"></span> American Samoa (+1-684)';
          optionsArr[4].innerHTML = '<span class="flag-icon flag-icon-and"></span> Andorra (+376)';
          optionsArr[5].innerHTML = '<span class="flag-icon flag-icon-ago"></span> Angola (+244)';
          optionsArr[6].innerHTML = '<span class="flag-icon flag-icon-aia"></span> Anguilla (+1-264)';
          optionsArr[7].innerHTML = '<span class="flag-icon flag-icon-ata"></span> Antarctica (+672)';
          optionsArr[8].innerHTML = '<span class="flag-icon flag-icon-atg"></span> Antigua and Barbuda (+1-268)';
          optionsArr[9].innerHTML = '<span class="flag-icon flag-icon-arg"></span> Argentina (+54)';
          optionsArr[10].innerHTML = '<span class="flag-icon flag-icon-arm"></span> Armenia (+374)';
          optionsArr[11].innerHTML = '<span class="flag-icon flag-icon-abw"></span> Aruba (+297)';
          optionsArr[12].innerHTML = '<span class="flag-icon flag-icon-aus"></span> Australia (+61)';
          optionsArr[13].innerHTML = '<span class="flag-icon flag-icon-aut"></span> Austria (+43)';
          optionsArr[14].innerHTML = '<span class="flag-icon flag-icon-aze"></span> Azerbaijan (+994)';
          optionsArr[15].innerHTML = '<span class="flag-icon flag-icon-bhs"></span> Bahamas (+1-242)';
          optionsArr[16].innerHTML = '<span class="flag-icon flag-icon-bhr"></span> Bahrain (+973)';
          optionsArr[17].innerHTML = '<span class="flag-icon flag-icon-bgd"></span> Bangladesh (+880)';
          optionsArr[18].innerHTML = '<span class="flag-icon flag-icon-brb"></span> Barbados (+1-246)';
          optionsArr[19].innerHTML = '<span class="flag-icon flag-icon-blr"></span> Belarus (+375)';
          optionsArr[20].innerHTML = '<span class="flag-icon flag-icon-bel"></span> Belgium (+32)';
          optionsArr[21].innerHTML = '<span class="flag-icon flag-icon-blz"></span> Belize (+501)';
          optionsArr[22].innerHTML = '<span class="flag-icon flag-icon-ben"></span> Benin (+229)';
          optionsArr[23].innerHTML = '<span class="flag-icon flag-icon-bmu"></span> Bermuda (+1-441)';
          optionsArr[24].innerHTML = '<span class="flag-icon flag-icon-btn"></span> Bhutan (+975)';
          optionsArr[25].innerHTML = '<span class="flag-icon flag-icon-bol"></span> Bolivia (+591)';
          optionsArr[26].innerHTML = '<span class="flag-icon flag-icon-bih"></span> Bosnia and Herzegovina (+387)';
          optionsArr[27].innerHTML = '<span class="flag-icon flag-icon-bwa"></span> Botswana (+267)';
          optionsArr[28].innerHTML = '<span class="flag-icon flag-icon-bra"></span> Brazil (+55)';
          optionsArr[29].innerHTML = '<span class="flag-icon flag-icon-iot"></span> British Indian Ocean Territory (+246)';
          optionsArr[30].innerHTML = '<span class="flag-icon flag-icon-vgb"></span> British Virgin Islands (+1-284)';
          optionsArr[31].innerHTML = '<span class="flag-icon flag-icon-brn"></span> Brunei (+673)';
          optionsArr[32].innerHTML = '<span class="flag-icon flag-icon-bgr"></span> Bulgaria (+359)';
          optionsArr[33].innerHTML = '<span class="flag-icon flag-icon-bfa"></span> Burkina Faso (+226)';
          optionsArr[34].innerHTML = '<span class="flag-icon flag-icon-bdi"></span> Burundi (+257)';
          optionsArr[35].innerHTML = '<span class="flag-icon flag-icon-khm"></span> Cambodia (+855)';
          optionsArr[36].innerHTML = '<span class="flag-icon flag-icon-cmr"></span> Cameroon (+237)';
          optionsArr[37].innerHTML = '<span class="flag-icon flag-icon-can"></span> Canada (+1)';
          optionsArr[38].innerHTML = '<span class="flag-icon flag-icon-cpv"></span> Cape Verde (+238)';
          optionsArr[39].innerHTML = '<span class="flag-icon flag-icon-cym"></span> Cayman Islands (+1-345)';
          optionsArr[40].innerHTML = '<span class="flag-icon flag-icon-caf"></span> Central African Republic (+236)';
          optionsArr[41].innerHTML = '<span class="flag-icon flag-icon-tcd"></span> Chad (+235)';
          optionsArr[42].innerHTML = '<span class="flag-icon flag-icon-chl"></span> Chile (+56)';
          optionsArr[43].innerHTML = '<span class="flag-icon flag-icon-chn"></span> China (+86)';
          optionsArr[44].innerHTML = '<span class="flag-icon flag-icon-cxr"></span> Christmas Island (+61)';
          optionsArr[45].innerHTML = '<span class="flag-icon flag-icon-cck"></span> Cocos Islands (+61)';
          optionsArr[46].innerHTML = '<span class="flag-icon flag-icon-col"></span> Colombia (+57)';
          optionsArr[47].innerHTML = '<span class="flag-icon flag-icon-com"></span> Comoros (+269)';
          optionsArr[48].innerHTML = '<span class="flag-icon flag-icon-cok"></span> Cook Islands (+682)';
          optionsArr[49].innerHTML = '<span class="flag-icon flag-icon-cri"></span> Costa Rica (+506)';
          optionsArr[50].innerHTML = '<span class="flag-icon flag-icon-hrv"></span> Croatia (+385)';
          optionsArr[51].innerHTML = '<span class="flag-icon flag-icon-cub"></span> Cuba (+53)';
          optionsArr[52].innerHTML = '<span class="flag-icon flag-icon-cuw"></span> Curacao (+599)';
          optionsArr[53].innerHTML = '<span class="flag-icon flag-icon-cyp"></span> Cyprus (+357)';
          optionsArr[54].innerHTML = '<span class="flag-icon flag-icon-cze"></span> Czech Republic (+420)';
          optionsArr[55].innerHTML = '<span class="flag-icon flag-icon-cod"></span> Democratic Republic of the Congo (+243)';
          optionsArr[56].innerHTML = '<span class="flag-icon flag-icon-dnk"></span> Denmark (+45)';
          optionsArr[57].innerHTML = '<span class="flag-icon flag-icon-dji"></span> Djibouti (+253)';
          optionsArr[58].innerHTML = '<span class="flag-icon flag-icon-dma"></span> Dominica (+1-767)';
          optionsArr[59].innerHTML = '<span class="flag-icon flag-icon-dom"></span> Dominican Republic (+1-809)';
          optionsArr[60].innerHTML = '<span class="flag-icon flag-icon-tls"></span> East Timor (+670)';
          optionsArr[61].innerHTML = '<span class="flag-icon flag-icon-ecu"></span> Ecuador (+593)';
          optionsArr[62].innerHTML = '<span class="flag-icon flag-icon-egy"></span> Egypt (+20)';
          optionsArr[63].innerHTML = '<span class="flag-icon flag-icon-slv"></span> El Salvador (+503)';
          optionsArr[64].innerHTML = '<span class="flag-icon flag-icon-gnq"></span> Equatorial Guinea (+240)';
          optionsArr[65].innerHTML = '<span class="flag-icon flag-icon-eri"></span> Eritrea (+291)';
          optionsArr[66].innerHTML = '<span class="flag-icon flag-icon-est"></span> Estonia (+372)';
          optionsArr[67].innerHTML = '<span class="flag-icon flag-icon-eth"></span> Ethiopia (+251)';
          optionsArr[68].innerHTML = '<span class="flag-icon flag-icon-flk"></span> Falkland Islands (+500)';
          optionsArr[69].innerHTML = '<span class="flag-icon flag-icon-fro"></span> Faroe Islands (+298)';
          optionsArr[70].innerHTML = '<span class="flag-icon flag-icon-fji"></span> Fiji (+679)';
          // More 169 Countries (Currently not added here) -
          optionsArr[71].innerHTML = 'No Data Found';


          // Create custom dropdown element and add class dropdown to it
          // Insert it in the DOM after the select field
          const customDropdown = document.createElement('div');
          customDropdown.classList.add('cc-dropdown');
          dropdown.insertAdjacentElement('afterend', customDropdown);

          // Create element for selected option
          // Add class to this element, text from the first option in select field and append it to custom dropdown
          const selected = document.createElement('div');
          selected.classList.add('cc-dropdown-selected');
          selected.innerHTML = 'Tel-Code';
          customDropdown.appendChild(selected);

          // Create element for dropdown menu, add class to it and append it to custom dropdown
          // Add click event to selected element to toggle dropdown menu
          const menu = document.createElement('div');
          menu.classList.add('cc-dropdown-menu');
          customDropdown.appendChild(menu);
          selected.addEventListener('click', toggleDropdown.bind(menu));

          // Create serach input element
          // Add class, type and placeholder to this element and append it to menu element
          const search = document.createElement('input');
          search.placeholder = 'Search Your Country...';
          search.type = 'text';
          search.classList.add('cc-dropdown-menu-search');
          menu.appendChild(search);

          // Create wrapper element for menu items, add class to it and append to menu element
          const menuItemsWrapper = document.createElement('div');
          menuItemsWrapper.classList.add('cc-dropdown-menu-items');
          menu.appendChild(menuItemsWrapper);

          // Loop through all options and create custom option for each option and append it to items wrapper element
          // Add click event for each custom option to set clicked option as selected option
          optionsArr.forEach(option => {
              const item = document.createElement('div');
              item.classList.add('cc-dropdown-menu-item');
              item.dataset.value = option.value;
              item.innerHTML = option.innerHTML;
              menuItemsWrapper.appendChild(item);

              item.addEventListener('click', setSelected.bind(item, selected, dropdown, menu));
          });

          // Add selected class to first custom option
          // menuItemsWrapper.querySelector('div').classList.add('selected');

          // Add input event to search input element to filter items
          // Add click event to document element to close custom dropdown if clicked outside of it
          // Hide original dropdown(select)
          search.addEventListener('input', filterItems.bind(search, optionsArr, menu));
          document.addEventListener('click', closeIfClickedOutside.bind(customDropdown, menu));
          dropdown.style.display = 'none';

      }


      // Toggle dropdown
      function toggleDropdown() {
          // Check if dropdown is opened and if it is close it, otherwise open it and focus search input

          if (this.offsetParent !== null) {
              this.style.display = 'none';
          } else {
              this.style.display = 'block';
              this.querySelector('input').focus();
          }
      }

      // Set selected option
      function setSelected(selected, dropdown, menu) {
          // Get value and label from clicked custom option
          const value = this.dataset.value;
          const label = this.innerHTML;

          // Change the text on selected element
          // Change the value on select field  

          filterDate = /(<spanb[^<>]*></span>s*)w+(?:s+w+)*s*((+[d-]+))/g;
          selected.innerHTML = label.replace(filterDate, `$1$2`);
          dropdown.value = value;

          // Close the menu
          // Reset search input value
          // Remove selected class from previously selected option and show all divs if they were filtered
          // Add selected class to clicked option
          menu.style.display = 'none';
          menu.querySelector('input').value = '';
          menu.querySelectorAll('div').forEach(div => {
              if (div.classList.contains('selected')) {
                  div.classList.remove('selected');
              }
              if (div.offsetParent === null) {
                  div.style.display = 'block';
              }
          });
          this.classList.add('selected');
      }

      // Filter items
      function filterItems(itemsArr, menu) {
          // Get all custom options
          // Get the value of search input and convert it to all lowercase characters
          // Get filtered items
          // Get the indexes of filtered items
          const customOptions = menu.querySelectorAll('.cc-dropdown-menu-items div');
          const value = this.value.toLowerCase();
          const filteredItems = itemsArr.filter(item => item.value.toLowerCase().includes(value));
          const indexesArr = filteredItems.map(item => itemsArr.indexOf(item));

          // Check if option is not inside indexes array and hide it and if it is inside indexes array and it is hidden show it


          var options = itemsArr.length;
          itemsArr.forEach(option => {
              if (!indexesArr.includes(itemsArr.indexOf(option))) {
                  customOptions[itemsArr.indexOf(option)].style.display = 'none';
                  options -= 1;
                  if (options <= 0) {
                      customOptions[itemsArr.length - 1].style.display = 'block';
                  }
              } else {
                  if (customOptions[itemsArr.indexOf(option)].offsetParent === null) {
                      customOptions[itemsArr.indexOf(option)].style.display = 'block';
                  }
              }
          });
      }

      // Close dropdown if clicked outside dropdown element
      function closeIfClickedOutside(menu, e) {
          if (e.target.closest('.cc-dropdown') === null && e.target !== this && menu.offsetParent !== null) {
              menu.style.display = 'none';
          }
      }


  });
 .cc-dropdown-menu-items::-webkit-scrollbar-track {
     background-color: #323757;
     width: 2px;
}
 .cc-dropdown-menu-items::-webkit-scrollbar {
     background-color: #323757;
     width: 14px;
}
 .cc-dropdown-menu-items::-webkit-scrollbar-thumb {
     background-color: #e8576f;
     border: 4px solid #323757;
     z-index: -1;
     width: 2px;
     min-height: 50px;
}
 #phone-number {
     width: calc(100% - 120px);
     margin-left: 120px;
}
 .frm div:nth-child(3) .inputBox .tx {
     margin-left: 120px;
}
 .frm div:nth-child(3) .inputBox {
     display: flex;
}
 .frm div:nth-child(3) .inputBox .ln {
     margin-left: 120px;
     width: calc(100% - 120px);
}
 .cc-dropdown {
     position: relative;
}
 .cc-dropdown-selected {
     display: flex;
     align-items: center;
     justify-content: center;
     width: 116px;
     height: 40px;
     padding: 0 20px 0 10px;
     position: relative;
     cursor: pointer;
     transition: box-shadow .3s ease;
     background-color: #323757;
     border-radius: 3px;
     font-size: 15px;
     color: #fff;
}
 .cc-dropdown-selected::after {
     top: calc(50% - 2px);
     right: 10px;
     border: solid transparent;
     content: '';
     height: 0;
     width: 0;
     position: absolute;
     border-top-color:#000;
     border-width: 4px;
     margin-left: -4px;
}
 .cc-dropdown-selected:hover {
     box-shadow: 0 0 5px rgba(0,0,0,0.1);
}
 .cc-dropdown-menu {
     position: absolute;
     top: 100%;
     left: 0;
     width: 273px;
     border: 3px solid #323757;
     margin-right: -2px;
     border-top: 0;
     background-color: #fff;
     z-index: +9;
     margin-top: 10px;
}
 .cc-dropdown-menu-items {
     max-height: 200px;
     width: 270px;
     overflow-y: auto;
     overflow-x: hidden;
     z-index: +9;
}
 .cc-dropdown-menu-search {
     display: block;
     width: 270px;
     border: 0;
     border-right: 3px solid #323757;
     padding: 14px 0px 14px 10px;
     font-size: 15px;
     font-weight: 550;
     color: #fff;
     outline: 0;
     background-color: #323757;
}
 .cc-dropdown-menu-search::placeholder {
     color: rgb(214, 214, 214)!important;
}
 .cc-dropdown-menu-item {
     width: 267px;
     border-bottom: 1px solid #323757a6;
     font-size: 14px;
     font-weight: 550;
     cursor: pointer;
     z-index: +9;
     user-select: none;
     padding: 10px 18px 10px 10px;
}
 .cc-dropdown-menu-items .flag-icon {
     height: 15px;
     width: 26px;
     margin-right: 3px;
}
 .cc-dropdown-menu-item:last-child {
     border-bottom: 0;
}
 .cc-dropdown-menu-item:hover {
     background-color: rgb(228, 228, 228);
}
 .cc-dropdown-menu-item.selected {
     border: none;
}
 .cc-dropdown-selected .flag-icon {
     margin-right: 5px!important;
}
 .cc-dropdown-menu-item.selected, .cc-dropdown-menu-item.selected:hover {
     background-color: #323757c2;
     color: #ffffff;
}
 .cc-dropdown-menu-item:last-child {
     pointer-events: none;
}
<div class="country-code-selector">
   <form class="cc-form">
      <div class="cc-form-group">
         <select id="country" name="country" cc-data-dropdown>
            <option value="Afganistan"></option>
            <option value="Albania"></option>
            <option value="Algeria"></option>
            <option value="American Samoa"></option>
            <option value="Andorra"></option>
            <option value="Angola"></option>
            <option value="Anguilla"></option>
            <option value="Antarctica"></option>
            <option value="Antigua and Barbuda"></option>
            <option value="Argentina"></option>
            <option value="Armenia"></option>
            <option value="Aruba"></option>
            <option value="Australia"></option>
            <option value="Austria"></option>
            <option value="Azerbaijan"></option>
            <option value="Bahamas"></option>
            <option value="Bahrain"></option>
            <option value="Bangladesh"></option>
            <option value="Barbados"></option>
            <option value="Belarus"></option>
            <option value="Belgium"></option>
            <option value="Belize"></option>
            <option value="Benin"></option>
            <option value="Bermuda"></option>
            <option value="Bhutan"></option>
            <option value="Bolivia"></option>
            <option value="Bosnia and Herzegovina"></option>
            <option value="Botswana"></option>
            <option value="Brazil"></option>
            <option value="British Indian Ocean Territory"></option>
            <option value="British Virgin Islands"></option>
            <option value="Brunei"></option>
            <option value="Bulgaria"></option>
            <option value="Burkina Faso"></option>
            <option value="Burundi"></option>
            <option value="Cambodia"></option>
            <option value="Cameroon"></option>
            <option value="Canada"></option>
            <option value="Cape Verde"></option>
            <option value="Cayman Islands"></option>
            <option value="Central African Republic"></option>
            <option value="Chad"></option>
            <option value="Chile"></option>
            <option value="China"></option>
            <option value="Christmas Island"></option>
            <option value="Cocos Islands"></option>
            <option value="Colombia"></option>
            <option value="Comoros"></option>
            <option value="Cook Islands"></option>
            <option value="Costa Rica"></option>
            <option value="Croatia"></option>
            <option value="Cuba"></option>
            <option value="Curacao"></option>
            <option value="Cyprus"></option>
            <option value="Czech Republic"></option>
            <option value="Democratic Republic of the Congo"></option>
            <option value="Denmark"></option>
            <option value="Djibouti"></option>
            <option value="Dominica"></option>
            <option value="Dominican Republic"></option>
            <option value="East Timor"></option>
            <option value="Ecuador"></option>
            <option value="Egypt"></option>
            <option value="El Salvador"></option>
            <option value="Equatorial Guinea"></option>
            <option value="Eritrea"></option>
            <option value="Estonia"></option>
            <option value="Ethiopia"></option>
            <option value="Falkland Islands"></option>
            <option value="Faroe Islands"></option>
            <option value="Fiji"></option>
            <option></option>
         </select>
      </div>
   </form>
</div>

Print part of page with javascript in Adobe Acrobat

I have a fill-in form in Adobe Acrobat with text fields and dropdown boxes.
When the fields are filled, the data go’s automatically in a badge-layout with javascript, that stands below the text fields on the same page.

I want to only print the badge file and not the text fields above the badge layout.
Is this possible with javascript? Can this be done with coordinates?

I can only find code to print the full page in javascript.

Webpack does not throw error despite missing component. Why?

I have been experimenting with React after upgrading to React 18 and did not understand why no error is thrown when a component is missing …

import                              './F1.css';

import React              from      'react';
import { useSelector }    from      'react-redux';

export default () => {
  return (
    <div id="app_hold">
      <F1Inner />
    </div>
  );
};

F1Inner does not exist, however, there is no error thrown by webpack

Uploading data with multer – image is an empty object

I want to send product data including an image to the database. I am using multer and get the error:

Cannot read property ‘path’ of undefined

I have seen that this error is very common and have tried the suggestions that are made on stack overflow without success. What makes me suspicious is, when I log the req.body, the correct data is displayed, but image is an empty object. I also logged the whole thing in my http-request, there image is a file and prototype array.

multer storage:

import { Request } from "express";
import multer, { FileFilterCallback } from "multer";
import path from 'path'
const maxSize = 100 * 1024 *1024;
type DestinationCallback = (error: Error | null, destination: string) => void
type FileNameCallback = (error: Error | null, filename: string) => void

 const storage = multer.diskStorage({
        destination:(req:Request,file:Express.Multer.File, callback:DestinationCallback)=>{
            callback(null, path.resolve(process.cwd(), 'admin/public/uploads'));
        },
    
        filename: (req:Request, file:Express.Multer.File, callback:FileNameCallback)=>{
            callback(null, Date.now()+ "--"+ path.extname(file.originalname))
        },    
    })

const upload = multer({
    storage:storage,
    fileFilter:(req:Request,file:Express.Multer.File,callback:FileFilterCallback)=>{
        if(
            file.mimetype == "image/png"||
            file.mimetype == "image/jpg" ||
            file.mimetype == "image/jpeg" ||
            file.mimetype == "video/mp4"
        ){
            callback(null, true);
        } else{
            callback(null,false)
            return callback(new Error("Only .png, .jpg, .jpeg, .mp3, .mp4 allowed"))
        }
    },
    limits:{fileSize: maxSize}
});

export default upload

;

My route: 

productsRouter.post('/', upload.single('image'), verifyTokenAndAdmin, async (req:Request, res:Response)=>{
    console.log(req.file);
    console.log(req.body);
    try{
        const uploadResult = cloudinary.uploader.upload(req.file!.path,{
            upload_preset: "webshop_ts_mern",
            resource_type: "auto",
        })
        const newProducts = new Products({
            cloudinary_id: uploadResult.public_id,
            title: req.body.title,
            producer: req.body.producer,
            categories: req.body.categories,
            desc: req.body.desc,
            price: req.body.price,
            currency:req.body.currency,
            colors:req.body.colors,
            sizes: req.body.sizes,
            inStock: req.body.inStock,
            image: uploadResult.secure_url,

        })
        const savedproducts = await newProducts.save();
        res.status(200).json(savedproducts);
    } catch(error){
        res.status(403)
        console.log(error);
        throw new Error("Action failed");
    }
});

Change value javascript

I want to change the value from “DDDDDD” to “helloee”
<input class="enter-code-input input-field form-control" type="text" placeholder="Enter 6 Character Code from New Device" value="DDDDDD">

I tried doing this:

document.querySelector('.enter-code-input.input-field.form-control').value='helloee';

But it redirects to a blank page with the text “helloee”

Christmas gift for a programmer in JavaScript code form

I want to place a simple “code” on a cup for my friend who programs in JavaScript. I myslef know nothing about it, I program a little bit only in VBA. I would like to do something like this:

…Success

For Each goal…
… consistency
… focus
… dedication
… Bart’sBigBrain

Close Loop

But I would like it to legitemately resemble JavaScript code, so it’s like you just put the words I used above into the actual code. If anyone here catches my drift I would appreciate help ^^

Well I have tried looking it up myself but it’s too damn complicated

HTML Alert – Exception: Cannot retrieve the next object: iterator has reached the end

I’m trying to call this upload script in an html alert in the spreadsheet:
drive-multi-upload

For that I’m using this function in the Code.gs file:

function showDialog(){                                              
const TEMPLATE = HtmlService.createTemplateFromFile('forms'); // calls the html page where the alert template will be
    
const HTML = TEMPLATE.evaluate().setWidth(600).setHeight(400); // we prepare the template to be loaded

SpreadsheetApp.getUi().showModalDialog(HTML, " "); // we load the template on the screen
}

The issue is that if another account clicks the button to upload the file, the message Exception: Unable to retrieve the next object: the iterator has reached the limit. is displayed.

How can I resolve this?

How ro use onclick event for mobile device?

i am currently working on project
i have using onclik method for search data on my chat app.
like below :-

    <div className="userChat"  id="myform" onClick={handleSelect} >
      <img src={user.photoURL} alt="" />
      <div className="userChatInfo">
        <span>{user.displayName}</span>
      </div>
    </div>

i want to use this line of code for mobile devices (screen touch) how can i do that?

Mysql, Nodejs, JS, Html, Css

Bonjour, je dois rendre un projet pour demain minuit et mes deux collègues ont abandonné. Bref je me retrouve dans le c*c*.

Je créer une webapp avec des quizz. j’ai le script pour le quizz,html,css tout est sur node js mais il me reste à gérer une base de donnée en mysql pour pouvoir enregistrer des utilisateurs avec mot de passe ainsi qu’un script pour pouvoir créer des quizz et les enregistrer directement sur le site( ca je vais peut être oublié).

Ma question : Par ou dois je commencer? je ne trouves rien qui réponde vraiment à ma question, comment me connecter à une base de donnée via node js? Je suis entrain de créer mes tables mais je ne sais pas comment les illustrer et jouer avec. Si vous avez une petite minute pour moi ce serait top ! Bonne journée.

J’ai essayer pleins de choses même télécharger des trucs tout fait pour comprendre les codes je n’arrivait pas à me connecter…

Cannot read properties of null ( play ) when leaving the component

  let phrase = "Head Admin Esports Middle East organization ( es.me website) and Project Manager at Arab Esports Website."
    let typedChar = "";
    let index = 0;
  let aud;

  const  typing = () =>  {
    setInterval(async () => {
        if (index < phrase.length) {
            typedChar += phrase[index];
            index++;
      await aud.play()
        } else {
      clearInterval()
        }
    }, 20)
  }
    onMount(() => {
    typing()
  })

enter image description here
here I am showing the data in typing effect I wanted to add sound to this typing effect it works fine as I wanted but when I leave the component mid typing it shows Cannot read properties of null ( play ) error

Can I do multiple search strings in a single JMESPath search?

I want to be able to perform multiple searches inside a JSON using JMESPath with JavaScript, so I don’t have to iterate over the large object for each JMESPath search string I need to perform.

I have this example object (let’s call it arrayItem):

{
  "domains": ["somedomain.com", "otherdomain.com"]
  "subdomains": ["mail", "docs"]
}

I’m trying to query both these fields and collect the data in a new array using JavaScript, like so:

const result = JMESPath.search(arrayItem, ["domains[]", "subdomains[]"])

Where one JMESPath search is “domains[]” and the other is “subdomains[]”.

But this does not work. I get null as a result. I have one solution, which is to perform the forEach() function for each of the items, but I don’t think this is the optimal way as I have to iterate over a huge dataset x number of times instead of a single search. The “hacky” solution provides the desired output when pushing each item to an array:

let whatIwantArray = []

jmesSearches = ["domains[]", "subdomains[]"]

jmesSearches.forEach((jmesSearch) => {
  const result = JMESPath.search(arrayItem, jmesSearch)

    result.forEach((domain) => {
    whatIWantArray.push(domain)
  })
})
console.log(whatIwantAraay)

output:
[“somedomain.com”, “otherdomain.com”, “mail”, “docs”]

If anyone knows if this can be done or not, and if so, how, I would greatly appreciate sollutions!