PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL instead. / Puppeteer windows 11

i tried to install puppeteer , i followed installation guide.

but after few seconds , it shows me this error:

.../node_modules/puppeteer postinstall$ node install.mjs
│ PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL instead.
│ ERROR: Failed to set up Chrome r119.0.6045.105! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.
│ Error: Download failed: server returned code 404. URL: https://npm.taobao.org/mirrors/119.0.6045.105/win64/chrome-win64.zip
│     at file:///C:/Users/Asus/Desktop/WorkSpace/Projects/test/Server/node_modules/.pnpm/@[email protected]/node_modules/@puppeteer/browsers/lib/esm/httpUtil.js:74:31
│     at ClientRequest.requestCallback (file:///C:/Users/Asus/Desktop/WorkSpace/Projects/torob/Server/node_modules/.pnpm/@[email protected]/node_modules/@puppeteer/browsers/lib/esm/httpUtil.js:52:13)
│     at Object.onceWrapper (node:events:629:26)
│     at ClientRequest.emit (node:events:514:28)
│     at HTTPParser.parserOnIncomingClient (node:_http_client:693:27)
│     at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17)
│     at TLSSocket.socketOnData (node:_http_client:535:22)
│     at TLSSocket.emit (node:events:514:28)
│     at addChunk (node:internal/streams/readable:376:12)
│     at readableAddChunk (node:internal/streams/readable:349:9)
└─ Failed in 5.1s at C:UsersAsusDesktopWorkSpaceProjectstorobServernode_modules.pnpmpuppeteer@21.6.0node_modulespuppeteer
 ELIFECYCLE  Command failed with exit code 1.

after some research i found out that using npm config set puppeteer_skip_chromium_download true might fix the problem but when i tried it , it showed me this:

npm ERR! `puppeteer_skip_chromium_download` is not a valid npm option

my node version: 20.9.0

npm version: 10.2.4

yarn version: 1.22.19

pnpm version : 8.11.0

(i used npm , yarn and pnpm)

My Socket web chat server does not show messages sent by users

Moreover, all the rooms are created and users can connect to the rooms, but when I send a message, the message is not sent. It is programmed in my code so that when a new user joins the room, the message you joined is sent so that others can see it, some kind of “John” and he can send messages and others also saw this but for some reason it doesn’t happen, what could this be connected with?

screenshot 1

screenshot 2

screenshot 3

Server js
`
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
app.set('views', './views');
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));

const rooms = {};

app.get('/', (req, res) => {
res.render('index', { rooms: rooms });
});

app.post('/room', (req, res) => {
if (rooms[req.body.room] != null) {
return res.redirect('/');
}
rooms[req.body.room] = { users: {} };
res.redirect(req.body.room);
//Send message that a new room was created
io.emit('room-created', req.body.room);
});

app.get('/:room', (req, res) => {
if (rooms[req.params.room] == null) {
return res.redirect('/');
}
res.render('room', { roomName: req.params.room });
});

server.listen(8080);

io.on('connection', socket => {
socket.on('new-user', (room, name) => {
socket.join(room);
rooms[room].users[socket.id] = name;
socket.to(room).broadcast.emit('user-connected', name);
});
socket.on('send-chat-message', (room, message) => {
socket.to(room).broadcast.emit('chat-message', { message: message, name:rooms[room].users[socket.id]            
});
socket.on('disconnect', () => {
getUserRooms(socket).forEach(room => {
socket.to(room).broadcast.emit('user-disconnected', rooms[room].users[socket.id]);
delete rooms[room].users[socket.id];
});
});
});
function getUserRooms(socket) {
return Object.entries(rooms).reduce((names, [name, room]) => {
if (room.users[socket.id] != null) names.push(name);
return names;
}[]);
}
`

/public/Script.js

`
const socket = io('http://vps.mydomen.com:8080')
const messageContainer = document.getElementById('message-container')
const roomContainer = document.getElementById('room-container')
const messageForm = document.getElementById('send-container')
const messageInput = document.getElementById('message-input')

if (messageForm != null) {
const name = prompt('What is your name?')
appendMessage('You joined')
socket.emit('new-user', roomName, name)

messageForm.addEventListener('submit', e => {
e.preventDefault()
const message = messageInput.value
appendMessage(`You: ${message}`)
socket.emit('send-chat-message', roomName, message)
messageInput.value = ''
})
}

socket.on('room-created', room => {
const roomElement = document.createElement('div')
roomElement.innerText = room
const roomLink = document.createElement('a')
roomLink.href = `/${room}`
roomLink.innerText = 'join'
roomContainer.append(roomElement)
roomContainer.append(roomLink)
})

socket.on('chat-message', data => {
appendMessage(`${data.name}: ${data.message}`)
})

socket.on('user-connected', name => {
appendMessage(`${name} connected`)
})

socket.on('user-disconnected', name => {
appendMessage(`${name} disconnected`)
})

function appendMessage(message) {
const messageElement = document.createElement('div')
messageElement.innerText = message
messageContainer.append(messageElement)
}
`
Client js
`
const socket = io('vps.mydomen.com:8081');

socket.on('message', msg => {
console.log(msg); 
});

document.querySelector('button').onclick = () => {
const msg = document.querySelector('input').value;
socket.emit('message', msg); 
}

`

/views/index.ejs

`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Chat App</title>
<script defer src="vps.mydomen.com:8080/socket.io/socket.io.js"></script>
<script defer src="script.js"></script>
</head>
<body>
<div id="room-container">
<% Object.keys(rooms).forEach(room => { %>
<div><%= room %></div>
<a href="/<%= room %>">Join</a>
<% }) %>
</div>
<form action="/room" method="POST">
<input name="room" type="text" required>
<button type="submit">New Room</button>
</form>
</body>
</html>
`

/views/room/room.ejs
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Chat App</title>
<script>
const roomName = "<%= roomName %>"
</script>
<script defer src="vps.mydomen.com:8080/socket.io/socket.io.js"></script>
<script defer src="script.js"></script>
<style>
body {
padding: 0;
margin: 0;
display: flex;
justify-content: center;
}

#message-container {
width: 80%;
max-width: 1200px;
}

#message-container div {
background-color: #CCC;
padding: 5px;
}

#message-container div:nth-child(2n) {
background-color: #FFF;
}

#send-container {
position: fixed;
padding-bottom: 30px;
bottom: 0;
background-color: white;
max-width: 1200px;
width: 80%;
display: flex;
}

#message-input {
flex-grow: 1;
}
</style>
</head>
<body>
<div id="message-container"></div>
<form id="send-container">
<input type="text" id="message-input">
<button type="submit" id="send-button">Send</button>
</form>
</body>
</html>
`

All the modules I need are installed. We are a VPS server I connected to my domain (vps.mydomain.com)

My vps server runs on port 8080, you can see this in my code

“Issue with @mui/material Drawer.js Import: ‘Slide’ Module Not Found”

ERROR in ./node_modules/@mui/material/Drawer/Drawer.js 155:28-33
export ‘default’ (imported as ‘Slide’) was not found in ‘../Slide’ (module has no exports) can anybody please tell me what kind of error is this even though i haven’nt use slide in any of my code then why this error is showing please help asap

i literally tried everything but the error still comes

How to use raw Buffer in Chainlink Functions?

Chainlink Functions currently offer some encoding functions for string, uint256 and int256, but it actually makes sense to send bytes to solidity in scenarios where for example you need to send multiple parameters or information so you can send it abi encoded.

Functions always need to return a Buffer, so if the provided encoders are not used you need to create your own buffer. For doing that in JS Buffer.from can be used, which works perfectly in Chainlink Functions Playground but it fails in practice when the function is used.

For my specific use case I want to do:

return Buffer.from(hexstring, 'hex');

where hexstring is my abi encoded data I want to send to the contract.

The error I got is:

TypeError: Cannot read properties of undefined (reading ‘from’)

I have also tried the old form of using Buffer like

return new Buffer(hexstring, 'hex');

which also works in the playground, but the error this time was that Buffer is not a constructor.

Given that it simply seems to not be imported one idea will be to just add a require in the Function but requires are not allowed, so it is not the way to go.

Microsoft speech recognition stopContinousRecognition does not work

I am trying to create a wrapper for the Microsoft Speech SDK to use in my vue componenet. The issue I am having is after calling startRecognition which calles startContinousRecognitionAsync, no other click even is being detected and it will not stop when I click stop and call the stopRecognition function. Here is the wrapper I created:

export default class SpeechRec {
    constructor(key, region) {
        this.key = key;
        this.region = region;
        this.speechRecognizer = undefined;
        this.stop = false;
    }

    createSpeechConfig() {
        return SpeechSDK.SpeechConfig.fromSubscription(this.key, this.region);
    }

    createRecognizer(speechConfig) {
        return new SpeechSDK.SpeechRecognizer(speechConfig);
    }

    createRecognizerWithLanguage(speechConfig, language) {
        return new SpeechSDK.SpeechRecognizer(speechConfig, language);
    }

    async startRecognition(nextAction) {
        console.log("STOP: ", this.stop)
        const speechConfig = this.createSpeechConfig();
        this.speechRecognizer = this.createRecognizer(speechConfig);
        this.speechRecognizer.BabbleTimeout = 0.75;
        const stopButton = document.querySelector(".stopButton")
        console.log(this.speechRecognizer)

        this.speechRecognizer.startContinuousRecognitionAsync();
        return new Promise(function(resolve, reject) {
            this.speechRecognizer.recognized = function (s, e) {
                if (e.result.reason === SpeechSDK.ResultReason.RecognizedSpeech) {
                    nextAction(e.result.text)
                    resolve(e.result.text);
                }
            };

            this.speechRecognizer.canceled = function (s, e) {
                if (e.reason === SpeechSDK.CancellationReason.Error) {
                    reject(e.reasonDetails);
                }
            };
        }.bind(this));
    }

    stopRecognition() {
        this.speechRecognizer.stopContinuousRecognition();
        this.speechRecognizer.close();
        
    }
}

Here is the vue component:

<template>
  <div>
    <button @click="startSpeechRec">Start</button>
    <button class="stopButton" @click="stopSpeechRec">Stop</button>
  </div>
</template>
<script>
import SpeechRec from '../Util/Speech';
export default {
  name: 'ReadingPage',
  data() {
    return {          
      speechRec: null,
      stopRecognitionRequested: false,
    };
  },
  props: [],
  created() {
    this.fetchReading();

  },
  mounted() {
    const stopButton = document.querySelector(".stopButton")
    stopButton.addEventListener("click", () =>{
            console.log(this.speechRec)
    })
  },
  methods: {
    stopSpeechRec(){
      this.speechRec.stopRecognition()
    },
    startSpeechRec(){
      this.stopRecognitionRequested = false;
      this.speechRec = new SpeechRec('Key', 'eastus');
      const textResult = this.speechRec.startRecognition();
    },

  },
};
</script>
<style>
.highlighted {
  background-color: yellow;
}
</style>

is it because I am using a promise? is there a better way of writing this? Neither the event listener I am adding on mount or the method stopSpeechRec are being called when I press stop.

Im hosting a Node.js server on A2hosting and I the following error in the console after ive set up my openSSL certificate – ERR_CERT_AUTHORITY_INVALID

Im hosting the node.js server on A2hosting. I have set up a self-signed certificate with openSSL on the node.js server but when I go to my website address, the webpage loads but in the console I can see the error message stating ERR_CERT_AUTHORITY_INVALID.

Here is my server code.

const path          = require('path');
const https        = require('https');
const express       = require('express');
const socketIO      = require('socket.io');
const { receiveMessageOnPort } = require('worker_threads');
const { stringify } = require('querystring');
const { count } = require('console');
const { kMaxLength } = require('buffer');
const publicPath    = path.join(__dirname, '/../public_html');
const port          = process.env.PORT || 3000;
const fs            = require('fs');

let app = express();
let server = https.createServer({
key: fs.readFileSync(path.join(__dirname, 'cert','key.pem'), 'utf8'),
cert: fs.readFileSync(path.join(__dirname, 'cert','cert.pem'), 'utf8'),
},app);
let io = socketIO(server);

app.use(express.static(publicPath));
server.listen(port, ()=> {
console.log(`Server is up on port ${port}.`)
});

Any help would be appreciated.

I’ve tried removing and reinstalling the certificate but it hasn’t helped. I’ve also seen other similar posts but they haven’t helped.

looking feedback on audit js, Node.js

My CTO is asking me to check vulnerabilities for every single dependencie and devDependency from my package.json

Is a super long boring tedieuse work

I’m looking ways to auto-audit and export a file .txt or excel giving information in each dependency and if it has or not any vulenerability.

I founded these website : https://ossindex.sonatype.org/
and i found they have these dependency called auditjs: https://www.npmjs.com/package/auditjs

I’m looking for feedbacks on these website/dependecy. If someone in the comunity trust it or not and why.

Some highlights :

  • Linux ubuntu
  • Node.js 18.18.0
  • package.json
  • npm

How to display output from my Dictionary Chrome Extension?

I want to create an extension that takes the selected text from the webpage, search about on a dictionary and return the definition. I think Im fine with the coding part, but I dont really understand how to display correctly my output.

My idea was to create a popup but I dont understand how to set the position of that popup, right now I was never able to move it away from right under the extension icon on Chrome.

Bonus:

  1. I’m also trying to set a different opacity on the background, to better display only text of the output, without a particular box background, but changing the alpha value doesnt seem to affect anything.
  2. Is it possible to open the popup with a single key instead of clicking the extension? I tried event listeners but they seem to be deaf.

background.js:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.action === 'searchDictionary') {
    var results = performDictionaryLookup(request.text);
    sendResponse({ results: results });
  }
});

function performDictionaryLookup(text) {
  var dictionaryData = loadDictionaryFromFile('dictionary.txt');
  var lowercaseText = text.toLowerCase();
  var results = findMatchingTerms(dictionaryData, lowercaseText);
  return results.length > 0 ? results : ['No definitions found for ' + text];
}

function loadDictionaryFromFile(filename) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', chrome.runtime.getURL(filename), false);
  xhr.send();
  var dictionaryContent = xhr.responseText;
  return JSON.parse(dictionaryContent);
}

function findMatchingTerms(dictionary, text) {
  var matchingTerms = [];
  for (const key in dictionary) {
    if (key.toLowerCase().includes(text)) {
      matchingTerms.push({ term: key, definition: dictionary[key] });
    }
  }
  return matchingTerms;
}

popup.js:

document.addEventListener('DOMContentLoaded', function() {
  chrome.tabs.executeScript({
    code: 'window.getSelection().toString();'
  }, function(selection) {
    var selectedText = selection[0].trim();
    console.log('Selected Text:', selectedText);

    if (selectedText !== '') {
      searchDictionary(selectedText);
    } else {
      document.getElementById('result').innerText = 'No text selected.';
    }
  });
});

function searchDictionary(text) {
  chrome.runtime.sendMessage({ action: 'searchDictionary', text: text }, function(response) {
    if (response && response.results) {
      console.log('Response:', response);

      var resultsContainer = document.getElementById('result');
      resultsContainer.innerHTML = ''; // Clear previous results

      if (response.results.length > 0) {
        response.results.forEach(function(result) {
          var resultElement = document.createElement('div');
          resultElement.innerText = result.definition;
          resultsContainer.appendChild(resultElement);
        });
      } else {
        resultsContainer.innerText = 'No definitions found for ' + text;
      }
    } else {
      console.error('Invalid or missing response:', response);
      document.getElementById('result').innerText = 'Error fetching dictionary entry.';
    }
  });
}

popup.html

<!-- popup.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dictionary Extension</title>
  <style>
    body {
      width: 200px; /* Adjust the width as needed */
      padding: 10px; /* Add padding for better spacing */
      background-color: rgba(255, 255, 255, 0.9); /* Set background color with transparency */
      border: 1px solid #ccc; /* Add a border */
      border-radius: 5px; /* Add rounded corners */
      font-family: 'Arial', sans-serif; /* Set font family */
      font-size: 9px; /* Set font size */
      color: #333; /* Set text color */
      margin: 0; /* Remove default margin for body */
    }

    p {
      margin: 0; /* Remove default margin for <p> */
    }
  </style>
</head>
<body>
  <!-- Your popup content goes here -->
  <p id="result">&gt; *output*</p>

  <script src="popup.js"></script>
</body>
</html>

manifest.json:

{
  "manifest_version": 2,
  "name": "Dictionary Extension",
  "version": "1.0",
  "description": "Lookup selected text in a Python dictionary.",
  "permissions": ["activeTab"],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

In Firefox, how do I prevent Ctrl+F in an element while keeping the element visible to the user?

My open-source library duplicates content as part of its aim to become a element for syntax-highlighted code. The user enters code into a <textarea> element, then the code is copied into a <pre><code> element displayed behind the <textarea> and highlighted with Prism.js/highlight.js.

An issue with this is that using Ctrl+F on the page returns duplicate results, a result for each occurrence in the <textarea> and another result for the same occurence in the <pre><code> element.

I have already implemented this fix using the CSS content property on the ::before pseudo-element which works perfectly on Google Chrome and Microsoft Edge, but it makes no difference in Mozilla Firefox (Firefox includes the CSS content attribute in Ctrl+F).

Can anyone suggest a Firefox-compatible fix? My library is an HTML custom element that must be as self-contained and customisable as possible, and I don’t want to make my own Ctrl+F search bar unless I really need to because the library must emulate a vanilla <textarea> as much as possible.

My JavaScript function has access to the code as text, the <textarea> element, and the <pre> and <pre><code> elements and can modify them before or after code is highlighted with each keystroke.

how do i make this code only book a date a maximum of 4 times

I want to make it so that the next available time will be after 4 hours. If a time gets booked twice, so for example if 10:00 gets booked twice, then the next available time will be 14:00.

I have tried a lot of different methods but none seem to work. I don’t know how to fix this.

var form = document.getElementById("my-form");

async function handleSubmit(event) {
  event.preventDefault();
  var status = document.getElementById("my-form-status");
  var data = new FormData(event.target);
  fetch(event.target.action, {
    method: form.method,
    body: data,
    headers: {
      'Accept': 'application/json'
    }
  }).then(response => {
    if (response.ok) {
      window.location.href = "confirmation.html"
      form.reset()
    } else {
      response.json().then(data => {
        if (Object.hasOwn(data, 'errors')) {
          status.innerHTML = data["errors"].map(error => error["message"]).join(", ")
        } else {
          status.innerHTML = "Tyvär, det uppstod ett problem, kontakta oss för hjälp"
        }
      })
    }
  }).catch(error => {
    status.innerHTML = "Tyvär, det uppstod ett problem, kontakta oss för hjälp"
  });
}

form.addEventListener("submit", handleSubmit)
<form id="my-form" action="https://formspree.io/f/xwkdgoqn" method="post">
  <label for="name">Your name:</label>
  <input type="text" name="name" id="name" required><br>
  
  <label for="email">Your email:</label>
  <input type="email" name="email" id="email" required><br>
  
  <label for="number">Your phone number:</label>
  <input type="tel" name="number" id="number" required><br>
  
  <label for="date">Date:</label>
  <input type="date" name="date" id="date" required><br>
  
  <label for="time">Time:</label>
  <select id="time" name="time" required>
    <option value="10:00">10:00</option>
    <option value="10:30">10:30</option>
    <option value="11:00">11:00</option>
    <option value="11:30">11:30</option>
    <option value="12:00">12:00</option>
    <option value="12:30">12:30</option>
    <option value="13:00">13:00</option>
    <option value="13:30">13:30</option>
    <option value="14:00">14:00</option>
    <option value="14:30">14:30</option>
    <option value="15:00">15:00</option>
    <option value="15:30">15:30</option>
    <option value="16:00">16:00</option>
  </select><br>
  
  <label for="paket-val">Choose package:</label>
  <select name="paket" id="paket">
    <option value="Wash with wax">Wash with wax</option>
    <option value="Wash outside and inside with wax">Wash outside and inside with wax</option>
    <option value="Wash outside and inside with polishing, claybar and wax">Wash outside and inside with polishing, claybar and wax</option>
    <option value="Full detail">Full detail</option>
  </select><br>
  
  <label for="message">Message for us:</label>
  <textarea name="message" id="message" cols="30" rows="5"></textarea><br>
  
  <input id="my-form-button" class="button" type="submit" value="Book now!">
  <p id="my-form-status"></p>
</form>

Problem with metadata and OrderService.list in Medusa.js

My problem is that I want to search for orders that have the status set to “711” in the metadata, but it only finds the first 10 orders and does not find those above the 10th order.

this is my code:

  const order = await this.OrderSerivce.list(
      {
        metadata: {
          status:"711"
        },
      },
      {
        relations: ["billing_address"],
        order: {
          [sortField]: sortOrder,
        },
      }
    )

Search by metadata doesnt work corect

I want to sort order list by the metadata tag like status, external_id

how to get base64 image from canvas

I have created a function. That function can read the uploaded image and get the imageData from the canves.

But I couldn’t get base64 image from that imagedata

Here is what I did

function handleFileSelect(event) {
    const file = event.target.files[0];

    if (file) {
        const reader = new FileReader();

        reader.onload = function (e) {
            const base64Data = e.target.result.split('base64,')[1];

            const img = new Image();
            img.src = "data:image/png;base64," + base64Data;

            img.onload = function() {
                const canvas = document.getElementById('imageCanvas');
                const ctx = canvas.getContext('2d');
                let imageData;
                
                canvas.width = img.naturalWidth;
                canvas.height = img.naturalHeight;
                 
                imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            };
        };

        reader.readAsDataURL(file);
    }
}

passport.session() seems to be breaking my app

This is my code. app.use(passport.session()) causes the app to crush.

const express = require('express');
const authRoutes = require('./routes/auth');
const mongoose = require('mongoose');
const passportSetup = require('./services/passport-setup');
const keys = require('./services/keys');
const cookieSession = require('cookie-session');
const profileRoutes = require('./routes/profile');
const passport = require('passport');

const app = express();

const PORT = 3000;

const MONGO_URL =
  'mongo-url-placeholder';

async function mongoConnect() {
  await mongoose.connect(MONGO_URL);
  console.log('Connection to MongoDb done');
}

app.set('view engine', 'ejs');

app.use(
  cookieSession({
    maxAge: 24 * 60 * 60 * 1000,
    keys: [keys.session.cookieKey],
  })
);

app.use(passport.initialize());
app.use(passport.session());

// Initialize Auth Routes
app.use('/auth', authRoutes);

// Profile Routes
app.use('/profile', profileRoutes);

app.use('/', (req, res) => {
  res.render('home');
});

async function startServer() {
  await mongoConnect();
  app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
  });
}

startServer();

Filtering items using RemoveChild() and appendChild()

I’m building a simple filter in Vanilla Javascript and CSS.

When the user click a category, the articles not related with the category have the class .hide. I also need to remove all these articles with the class .hide from the DOM, and append them again when the user click the category related to them.

The filter works fine adding and removing the class .hide. But the issue is, once the hidden articles have been removed, they don’t appear again.

The JS:

const filterBox = document.querySelectorAll('.js-article');

document.querySelector('.js-filter-list').addEventListener('click', (event) => {

    if (event.target.tagName !== 'BUTTON') return false;
    let filterClass = event.target.dataset['filter'];

    filterBox.forEach(elem => {
        elem.classList.remove('hide');
        elem.parentNode.appendChild(elem);

        if (!elem.classList.contains(filterClass) && filterClass !== 'all') {
            elem.classList.add('hide');
            elem.parentNode.removeChild(elem);
        }
    });

});

The HTML:

<div class="c-filter__list js-filter-list">
    <button class="c-filter__list-item is-active js-filter-item" data-filter="all">All</button>
    <button class="c-filter__list-item o-font-title js-filter-item" data-filter="cat-1">Cat 1</button>
    <button class="c-filter__list-item o-font-title js-filter-item" data-filter="cat-2">Cat 2</button>
    <button class="c-filter__list-item o-font-title js-filter-item" data-filter="cat-3">Cat 3</button>
    <button class="c-filter__list-item o-font-title js-filter-item" data-filter="cat-4">Cat 4</button>
</div>

<article class="js-article cat-1"></article>
<article class="js-article cat-2"></article>
<article class="js-article cat-2 cat-3"></article>
<article class="js-article cat-1" ></article>
<article class="js-article cat-4"></article>
<article class="js-article cat-3 cat-4"></article>
...

Thank you.