Combine code from prerender.io with cloudflare worker

I have this “route” setup in the Cloudflare worker, where it’ll change http header tags to index for certain pages.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);

  // Clone the response so that it's no longer immutable
  const newResponse = new Response(response.body, response);


  // Adjust the value for an existing header
  newResponse.headers.set('x-robots-tag', 'index');

  return newResponse;
}

Works well but cloudflare will skip my other worker , which is a “less specific route” ( the prerender code )

/**
 * Basic settings
 */

// The API key visible on your Prerender dashboard.
const API_KEY = 'XXXX';

// The domains that you want to be prerendered.
const PRERENDERED_DOMAINS = [
  'sub.example.com'

];

/**
 * Advanced settings
 */

 // These are the user agents that the worker will look for to
 // initiate prerendering of the site.
const BOT_AGENTS = [
  'googlebot',
  'yahoo! slurp',
  'bingbot',
  'yandex',
  'baiduspider',
  'facebookexternalhit',
  'twitterbot',
  'rogerbot',
  'linkedinbot',
  'embedly',
  'quora link preview',
  'showyoubot',
  'outbrain',
  'pinterest/0.',
  'developers.google.com/+/web/snippet',
  'slackbot',
  'vkshare',
  'w3c_validator',
  'redditbot',
  'applebot',
  'whatsapp',
  'flipboard',
  'tumblr',
  'bitlybot',
  'skypeuripreview',
  'nuzzel',
  'discordbot',
  'google page speed',
  'qwantify',
  'pinterestbot',
  'bitrix link preview',
  'xing-contenttabreceiver',
  'chrome-lighthouse',
  'telegrambot'
];

// These are the extensions that the worker will skip prerendering
// even if any other conditions pass.
const IGNORE_EXTENSIONS = [
  '.js',
  '.css',
  '.xml',
  '.less',
  '.png',
  '.jpg',
  '.jpeg',
  '.gif',
  '.pdf',
  '.doc',
  '.txt',
  '.ico',
  '.rss',
  '.zip',
  '.mp3',
  '.rar',
  '.exe',
  '.wmv',
  '.doc',
  '.avi',
  '.ppt',
  '.mpg',
  '.mpeg',
  '.tif',
  '.wav',
  '.mov',
  '.psd',
  '.ai',
  '.xls',
  '.mp4',
  '.m4a',
  '.swf',
  '.dat',
  '.dmg',
  '.iso',
  '.flv',
  '.m4v',
  '.torrent',
  '.woff',
  '.ttf',
  '.svg',
  '.webmanifest'
];

/**
 * This attaches the event listener that gets invoked when CloudFlare receives
 * a request.
 */
addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);
  const { hostname } = url;
  const requestUserAgent = (request.headers.get('User-Agent') || '').toLowerCase();
  const xPrerender = request.headers.get('X-Prerender');
  const pathName = url.pathname.toLowerCase();
  const ext = pathName.substring(pathName.lastIndexOf('.') || pathName.length);

  if (
    !xPrerender
    && containsOneOfThem(BOT_AGENTS, requestUserAgent)
    && !isOneOfThem(IGNORE_EXTENSIONS, ext)
    && isOneOfThem(PRERENDERED_DOMAINS, hostname)
  ) {
    event.respondWith(prerenderRequest(request))
  }
})

/**
 * Helper function to check if an array contains an exact match for an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function isOneOfThem(array, element) {
  return array.some(e => e === element);
}

/**
 * Helper function to check if an array contains an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function containsOneOfThem(array, element) {
  return array.some(e => element.indexOf(e) !== -1);
}

/**
 * Function to request the prerendered version of a request.
 *
 * @param {Request} request - The request received by CloudFlare
 * @returns {Promise<Response>}
 */
function prerenderRequest(request) {
  const { url, headers } = request;
  const prerenderUrl = `https://service.prerender.io/${url}`;
  const headersToSend = new Headers(headers);

  headersToSend.set('X-Prerender-Token', API_KEY);

  const prerenderRequest = new Request(prerenderUrl, {
    headers: headersToSend,
    redirect: 'manual',
  });

  return fetch(prerenderRequest);
}

So I need to combine them both but I’m missing something, everything I try throws an error when I “Save and deploy” the Cloudflare worker.

Here was my one of my attempts

 /**
 * Basic settings
 */

// The API key visible on your Prerender dashboard.
const API_KEY = 'XXXX';

// The domains that you want to be prerendered.
const PRERENDERED_DOMAINS = [
  'sub.example.com'

];

/**
 * Advanced settings
 */

 // These are the user agents that the worker will look for to
 // initiate prerendering of the site.
const BOT_AGENTS = [
  'googlebot',
  'yahoo! slurp',
  'bingbot',
  'yandex',
  'baiduspider',
  'facebookexternalhit',
  'twitterbot',
  'rogerbot',
  'linkedinbot',
  'embedly',
  'quora link preview',
  'showyoubot',
  'outbrain',
  'pinterest/0.',
  'developers.google.com/+/web/snippet',
  'slackbot',
  'vkshare',
  'w3c_validator',
  'redditbot',
  'applebot',
  'whatsapp',
  'flipboard',
  'tumblr',
  'bitlybot',
  'skypeuripreview',
  'nuzzel',
  'discordbot',
  'google page speed',
  'qwantify',
  'pinterestbot',
  'bitrix link preview',
  'xing-contenttabreceiver',
  'chrome-lighthouse',
  'telegrambot'
];

// These are the extensions that the worker will skip prerendering
// even if any other conditions pass.
const IGNORE_EXTENSIONS = [
  '.js',
  '.css',
  '.xml',
  '.less',
  '.png',
  '.jpg',
  '.jpeg',
  '.gif',
  '.pdf',
  '.doc',
  '.txt',
  '.ico',
  '.rss',
  '.zip',
  '.mp3',
  '.rar',
  '.exe',
  '.wmv',
  '.doc',
  '.avi',
  '.ppt',
  '.mpg',
  '.mpeg',
  '.tif',
  '.wav',
  '.mov',
  '.psd',
  '.ai',
  '.xls',
  '.mp4',
  '.m4a',
  '.swf',
  '.dat',
  '.dmg',
  '.iso',
  '.flv',
  '.m4v',
  '.torrent',
  '.woff',
  '.ttf',
  '.svg',
  '.webmanifest'
];

/**
 * This attaches the event listener that gets invoked when CloudFlare receives
 * a request.
 */
addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);
  const { hostname } = url;
  const requestUserAgent = (request.headers.get('User-Agent') || '').toLowerCase();
  const xPrerender = request.headers.get('X-Prerender');
  const pathName = url.pathname.toLowerCase();
  const ext = pathName.substring(pathName.lastIndexOf('.') || pathName.length);

  if (
    !xPrerender
    && containsOneOfThem(BOT_AGENTS, requestUserAgent)
    && !isOneOfThem(IGNORE_EXTENSIONS, ext)
    && isOneOfThem(PRERENDERED_DOMAINS, hostname)
  ) {
    event.respondWith(prerenderRequest(request))
  }
})
 addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);

  // Clone the response so that it's no longer immutable
  const newResponse = new Response(response.body, response);


  // Adjust the value for an existing header
  newResponse.headers.set('x-robots-tag', 'index');

  return newResponse;

/**
 * Helper function to check if an array contains an exact match for an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function isOneOfThem(array, element) {
  return array.some(e => e === element);
}

/**
 * Helper function to check if an array contains an element or not.
 *
 * @param {string[]} array - The array to check.
 * @param {string} element - The element to check if the array contains.
 * @returns {boolean}
 */
function containsOneOfThem(array, element) {
  return array.some(e => element.indexOf(e) !== -1);
}

/**
 * Function to request the prerendered version of a request.
 *
 * @param {Request} request - The request received by CloudFlare
 * @returns {Promise<Response>}
 */
function prerenderRequest(request) {
  const { url, headers } = request;
  const prerenderUrl = `https://service.prerender.io/${url}`;
  const headersToSend = new Headers(headers);

  headersToSend.set('X-Prerender-Token', API_KEY);

  const prerenderRequest = new Request(prerenderUrl, {
    headers: headersToSend,
    redirect: 'manual',
  });

  return fetch(prerenderRequest);
}

How to convert detected url in text to link in React?

I am making a SNS website and trying to convert detected url in text to shown as links.

import React from "react";
import "./PostCard.css";
import { useNavigate } from "react-router-dom";
import datePretty from "../../helperFunctions/datePretty";

function PostCard({ userName, postTime, likeCount, commentCount, postText }) {

  var pastTime = datePretty(postTime)

  return (
    <div className="postingCard">
      <div className="postingHeader">
        <div className="postingProfile">
          <img className="postPP" src="profile.png" alt="Sample profile"></img>
        </div>
        <div className="postingWriter">
          <h3>{userName}</h3>
        </div>
        <div className="dateWritten">
          <h4>Posted {pastTime} ago</h4>
        </div>
        <div className="postSetting">
          <i className="fa-solid fa-ellipsis fa-2xl" id="postSet"></i>
        </div>
      </div>
      <div className="postingBody">
        <div className="postingSection">
          <div className="postWords">
            <h4>{postText}</h4>
          </div>
        </div>
        <div className="iconSection">
          <div className="likeSection">
            <i className="fa-regular fa-thumbs-up fa-2xl" id="like"></i>
            <div className="likeCount" id="likeNum">
              {likeCount}
            </div>
          </div>
          <div className="commentSection">
            <i className="fa-regular fa-comment-dots fa-2xl"></i>
            <h5 className="commentCount">{commentCount}</h5>
          </div>
        </div>
      </div>
    </div>
  );
}

export default PostCard;

This is my code that I currently working on. The postText is the element that I tried to convert to shown as link.

For example, when I uploaded like “hello, https://www.youtube.com”, then https://www.youtube.com should be able to click and redirect to YouTube.

Can you please tell me how to figure this out?

Get name of prototype method

This is my prototype:

Object.defineProperty(Set.prototype, 'isSubsetOf', {
    value: function(this: Set<string>, otherSet: Set<string>): boolean { ... }
})

I want something that will give the name of Set.isSubsetOf, which is: "isSubsetOf"


The following is my attempt to retrieve the name of Set.isSubsetOf:

console.log(Set.prototype.isSubsetOf.name);  // output: "value"

Why do I want it?

So that I can generate more descriptive test suite names:

describe(`unit-test: Set.prototype.${Set.prototype.isSubsetOf.name} method`, () => { ... });

How to click on a DOM element by its text using Puppeteer?

I’m trying to click on a li HTML DOM element using its text like so:

const insightNavLink = await page.$x('//li[text()="Insight"]');
await page.click(insightNavLink[0]); // error because it returns an empty array

I would have love to use a better selector as id, class or data-id attribute, but it’s not available.

I also tried using vanilla JavaScript like so:

const getElementByItsContent = (el, content) => document.querySelector(`${el}:contains("${content}")`);

const insightNavLink = getElementByItsContent('li', 'Insight');
console.log(insightNavLink);

But I get the error: ReferenceError: document is not defined (I am not in headless mode)

Any ideas?

How to fix “Uncaught TypeError: db.collection is not a function”?

code in which the error occurs:

const countRef = db.collection('counter').doc('counter');
const increment = firebase.Firestore.FieldValue.increment(1);
const decrement = firebase.Firestore.FieldValue.increment(-1);
function change(num) {
    if (num>0) {
        countRef.update({ counter: increment });
    } else if (num<0) {
        countRef.update({ counter: decrement });
    };
};

The error is in the first line of code.

vuex store episode.characters is undefined

I am trying to get data from API through vuex.

This is an action function in store:

async getEpisodeFromApi({ commit }, id) {
      const data = {
        id
      };

      return await axios.get(Api.getUrl(data)).then((response) => {
        console.log("response.dat0dfgsdfa", response.data);
        commit("setEpisode", response.data);
      });
    }

This is an Api class (it returns the link string):

class Api {
  getUrl(data) {
    return "https://www.breakingbadapi.com/api/episodes/" + data.id;
  }
}

export default new Api();

And this is how I tried to interact with data.

 async beforeCreate() {
    await this.$store.dispatch(
      "getEpisodeFromApi",
      this.$route.params.episode_id
    );
  },
  async mounted() {
    const episode = this.$store.state.episode;
    episode.characters.forEach((name) => {
      this.charactersInEpisode.push(
        this.$store.characters.find((character) => character.name === name)[0]
      );
    });
}

But store fills state slowlier than mounted hooks begin to work. And I always get episode as an empty variable and episode.characters is undefined.

episode.characters is undefined

How can I fill state in store and get the data from store faster than mounted hook runs code?

Replacement for ActiveXObject(“MSXML2.XMLHTTP”);

Refactoring old javascript code, what is an effective replacement of ActiveX? Below is an example of how it is being used.

var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
var sURL = homeURL + "/Utility.asmx";
xmlhttp.Open("POST", sURL, false);
xmlhttp.setRequestHeader("SOAPAction", "http://tempuri.org/DestroyScreen");
xmlhttp.setRequestHeader("Content-Type", "text/xml");
var sPayload = "<?xml version="1.0" encoding="utf-8"?>";
sPayload += "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>";
sPayload += "<soap:Body>";
sPayload += "<DestroyScreen xmlns='http://tempuri.org/'>";
sPayload += "<screenID>" + WebScreen.ScreenID + "</screenID>";
sPayload += "<instanceID>" + WebScreen.ScreenInstance + "</instanceID>";
sPayload += "</DestroyScreen>";
sPayload += "</soap:Body>";
sPayload += "</soap:Envelope>";
xmlhttp.Send(sPayload);

Looping through an array of arrays and removing an item

My question is quite odd because it’s for OfficeScripts. I am pretty sure it is Javascript-based because that is what I have been writing in. Now onto my question. I have an array of arrays that I am backward looping through in order to remove some items. basically, I gathered row data from one table and then used it to filter other tables, and then built an array of an array using both data.
looking something like this:

const Data = [["A", "B", "C", "D",]];
const otherData = [[1,2,3,4],[5,6,7,8],[9,10,11,12]];
var CombinedData = otherData.map(x=>[...Data[0], ...x]);
console.log(CombinedData);

What I am looking to accomplish is to remove the “C” from every array in the CombinedData array of arrays. Right now I am writing this and it’s emptying my array:

const Data = [["A", "B", "C", "D",]];
    const otherData = [[1,2,3,4],[5,6,7,8],[9,10,11,12]];
    var CombinedData = otherData.map(x=>[...Data[0], ...x]);
    console.log(CombinedData);
    
    for(let i = CombinedData.length -1; i>=0; i--){
      if(CombinedData[i][2] == Data[0][2]){
        CombinedData[i].splice(i,1);
          
      }
    }
    console.log(CombinedData);
  
    

Which obviously isn’t working. Any thoughts on what I need to do? JavaScript isn’t my strongest language, and I am completely new to OfficeScripts. I appreciate any help.

Find greater of two objects based on key value Javascript Reduce

I’ve been trying for 3 days straight to figure this out, by this point I don’t even know what to search for.

I have an array of objects, I would like to get the greatest “bid_amount” for each “item_id”, and then use the item_id, bid_amount and bidder_id in the DOM. I am stuck at the first step.

[
    {
        "item_id": "1",
        "bid_amount": "765432",
        "bidder_id": "298709"
    },
    {
        "item_id": "1",
        "bid_amount": "380",
        "bidder_id": "606396"
    },
    {
        "item_id": "2",
        "bid_amount": "545",
        "bidder_id": "606396"
    },
    {
        "item_id": "2",
        "bid_amount": "525",
        "bidder_id": "317740"
    },
    {
        "item_id": "2",
        "bid_amount": "505",
        "bidder_id": "606396"
    },]
function getBids() {
  var request = new XMLHttpRequest();
  request.open('POST', '/get_bids.php', true);
  request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');

  request.onload = function() {
    bids = JSON.parse(this.response)

    bids.reduce(function(prev, curr) {
      currItemId = curr.item_id
      currBidAmnt = curr.bid_amount

      const item_id = (prev[curr.item_id] || []);
      const prevBidsForId = prev[currItemId];

      if (prevBidsForId) {
        console.log(' a bid for this item exists, now i need to check if the current bid amount is greater than the previous bid amount for this item ')

        item_id.push(curr)
        prev[currItemId] = item_id
      } else {
        // push current item to prev
        console.log(' a bid for this item does not exist ')

        item_id.push(curr)
        prev[currItemId] = item_id
      }
      return prev
    }, [])
  }

gallery with modal window

I am creating a gallery in PHP. Clicking on each thumbnail should open a modal window with the image and other information.
The problem is that it only works with the first thumbnail and not with the others.
this is part of the php code:

        while($i !== $nIMG){
        $recordIMG = $q->fetch(PDO::FETCH_ASSOC);
        echo "<div class='content-img'><img src='". $recordIMG['urljpg'] ."' id='infoIMG'></div>";

        $i++;
    }  

this is the modal window

        <div class="modal" id="myModal">
        <img class="modal-content" id="img01">
        </div>

this is the javascript code

        var modal = document.getElementById("myModal");
        var img = document.getElementById("infoIMG");
        var modalImg = document.getElementById("img01");
        img.onclick = function(){
        modal.style.display = "block";
        modalImg.src = this.src;
     }

I am thinking it is an ID issue which must be unique. But I don’t know how to solve, could someone more experienced help me?

OpenWeather API endpoint fetch

https://javascript.plainenglish.io/display-7-day-weather-forecast-with-openweather-api-aac8ba21c9e3

I’m having trouble implementing this into my project. I can’t get it to display weather on the page. I believe I need to render it to the page?

    forecastEl[0].classList.add('loaded');

    response.json().then(function (data) {
        var fday = "";
        data.daily.forEach((value, index) => {
            if (index > 0) {
                var dayname = new Date(value.dt * 1000).toLocaleDateString("en", {
                    weekday: "long",
                });
                var icon = value.weather[0].icon;
                var temp = value.temp.day.toFixed(0);
                fday = `<div class="forecast-day">
                    <p>${dayname}</p>
                    <p><span class="ico-${icon}" title="${icon}"></span></p>
                    <div class="forecast-day--temp">${temp}<sup>°C</sup></div>
                </div>`;
                forecastEl[0].insertAdjacentHTML('beforeend', fday);
            }
        });
    });

Thank you!

Trouble accessing AWS HTTP API via ajax

Having errors with my code in accessing AWS HTTP API

When accessing it via browser https://randomAlphanumeric.execute-api.region.amazonaws.com/endpoint?param=paramValue

it returns the correct json object

{
   "username" : "clientUserName",
   "url" : "url"
}

but when i am accessing it via jQuery, it returns error 500 with no additional help

sample code

$.ajax({
        url: "https://randomAlphanumeric.execute-api.region.amazonaws.com/endpoint?param=paramValue",
        type: 'GET',
        beforeSend: function(request) {
            request.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
            request.setRequestHeader('Access-Control-Allow-Origin', "*");
            request.setRequestHeader('Access-Control-Allow-Method', '*');
            request.setRequestHeader('Access-Control-Allow-Headers', "*");
            },
        success: function(res) {
            console.log(res);
            alert(res);
        }
    });

I have already allowed all origins in the CORS setting in the HTTP API

How to click on popup contents in Puppeteer?

I used the following but am not able to set focus on the input field of the ‘deliver to’ popup and enter information.

(async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    const url = 'https://www.tntsupermarket.com/eng/store-flyer';
    await page.goto(url, {waitUntil: 'networkidle0'});

    const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
    await page.evaluate(()=> {
        document.querySelector('span[class="deliverCss-city-FJJ"]').click();
    });
    const popup = await newPagePromise;
    await popup.waitForSelector('input[aria-label="Enter your Postal Code"]');
    await popup.focus('input[aria-label="Enter your Postal Code"]');
    await popup.click('input[aria-label="Enter your Postal Code"]');
    await popup.keyboard.type('123');

})();