IntersectionObserver is not triggered when div ref is conditionally rendered

I’m trying to build infinite scroll pagination in React, and using JavaScript’s IntersectionObserver to attach a load more div. Basically when the user scrolls down to the table then – Loading... text will come up and an API is being called to fetch the table contents from backend. The issue is If I show the Loading... text without any conditional rendering , then the IntersectionObserver is being properly triggered but when I add a condition to render the Loading... text then the IntersectionObserver is not being triggered at all.

From the backend API , I will be getting numberOfPages variable , which will define how many pages/ records present in db , in return Loading... text shouldn’t come up after it reaches the last page. This is what I’ve tried so far. Also tried one of the blog i found out
Blog Link.

Codesandbox code : Code link

Live : Live demo here

In top Level of a script, is lexicalEnvironment the same as variableEnvironment

I have browsed many similar questions and ECMA262 2022 for some days, but still don’t know why.

  1. I know LE is the same as VE originally, does it means that they point to one Environment Record.
  2. in the top level of the script, if contains let or const declarations, will a new Environment Record be created and LE point to it?

Am I right to think it as following?

let a = 1
var b = 2
console.log(a)
---------------------------
// Pseudo codeļ¼š
// which right? or other else

global Execution Context = {
  VE: {
    bindings: b
    [[outerEnv]]: null
  },
// create a new ER whose [[outerEnv]] is null. then LE point to it.
  LE: {
    bindings: a
    [[outerEnv]]: null
  }
}

or

global Execution Context = {
  VE: {
    bindings: b
    [[outerEnv]]: null
  },
// create a new ER whose [[outerEnv]] is the original ER (which the unchangeable VE point to)
// then LE point to it
  LE: {
    bindings: a
    [[outerEnv]]: VE
  }
}

How to pass session attribute to Websocket on creation?

I’m making a basic chat application with JSTL and Jakarta WebSockets but need to be able to pass a user’s group code to the websocket on open. I thought about adding the following meta tag to the HTML file

<meta name="group" content="${group}"/>

since “group” is stored as a session attribute. I then try to access this data in the following javascript file (where the websocket is created). Unfortunately I cannot do this since document doesn’t exist outside of functions. I added a comment to the line I am referring to.

var wsUrl;
if (window.location.protocol == 'http:') { wsUrl = 'ws://'; }
else { wsUrl = 'wss://'; }

var group = document.querySelector('meta[name=group]').content; //How can i access this info??
var socket = new WebSocket(wsUrl + window.location.host + "/ChoreSplitter/message?group=" + "123");
        
socket.onmessage = function(event) {
    var mySpan = document.getElementById("chat");
    mySpan.innerHTML += event.data;
};
     
socket.onerror = function(event) {
    console.log("Chat Error ", event)
} 

function sendMsg() {
    var msg = document.getElementById("msg").value;
    if (msg) {
        socket.send(msg);
    }
    document.getElementById("msg").value = "";
}

Anyone have suggestions for a better way to pass this session data on creation of my web socket? Could I potentially send this data from a servlet to the ServerEndpoint?

How do trigger a rerender based on a timer but only on a specific component in React

I have a component that renders relative time

import React, { useEffect, useRef, useReducer } from 'react'
import { Text, TextProps } from 'react-native';
import { formatDistanceToNow } from 'date-fns';
type MomentTextProps = Omit<TextProps, 'children'> & {
  date: Date | number;
  pollTimeMs?: number;
}
export function MomentText({
  date, 
  pollTimeMs = 60000,
  ...props}: MomentTextProps) : JSX.Element {
  const [ formatted, update ] = useReducer(
    () => formatDistanceToNow(Date.now())
  );
  const timeoutRef = useRef<ReturnType<typeof setTimeout>>();
  useEffect(()=> {
    timeoutRef.current = setTimeout(update, pollTimeMs);
    return () => {
      clearTimeout(timeoutRef.current!);
    };
  });

  return <Text {...props}>{formatted}</Text>
}

Which works, but seems overkill that I am creating so many timeouts, I was wondering if there’s a way of doing this via a “React context” but only rerender this one specific child.

The way I am thinking of it (as I type this) is to have a subscribe/notify hook like this…

/**
 * This hook provides a simple subscription semantic to React components.
 */
export function useSubscription<T = unknown>(): SubscriptionManager<T> {
  const subscribersRef = useRef<((data: T) => void)[]>([]);
  function subscribe(fn: (data: T) => void) {
    subscribersRef.current.push(fn);
    return () => {
      subscribersRef.current = subscribersRef.current.filter(
        (subscription) => !Object.is(subscription, fn)
      );
    };
  }
  function notify(data: T) {
    subscribersRef.current.forEach((fn) => fn(data));
  }
  function useSubscribeEffect(fn: (data: T) => void) {
    useEffect(() => subscribe(fn), []);
  }
  return { subscribe, notify, useSubscribeEffect };
}

and have a useRef and useEffect that will call notify on the MomentText component.

Seems quite overkill but not really sure which is worse.

The first approach is easy to understand, but may be a performance hit

The second is a bit more complicated, but the usage is isolated since it’s just a context requirement and everything else can be handled by subscriptions within the component.

Click event not fired when clicking on canvas in Chrome during animation (works in Firefox)

My janky flying rat game

Working on this janky little flying rat game.

I’m planning on having the rat shoot cheese bullets in the direction of the mouse pointer. I am adding click event listeners – currently on window, but will be on canvas afterwards.

The click event currently prints the mouse position to console

When I open the game, the click event fires and prints to console regardless of where I click.

Once the canvas switches from the introduction “page” to the actual game, the click event stops firing when clicking on the canvas – yet it keeps firing click events outside of the canvas.

This issue happens in Chrome. In Firefox there is no issue.

I also noticed that when looking at elements in chrome dev tools, once the introduction page ends, and the game starts, the body block (in “elements section”) starts flickering. I’m thinking this may be related.

I can’t see what is so different about how the introduction page canvas and the gameplay are animated/drawn to cause this issue.

How to run if conditional, can meet twice

I have a condition like this, I want the first if conditional to have no reaction if you meet this condition again the second time give him a reaction, more or less like the example in the code below.

var x = -1;

if( x < 0){
  console.log("is okay")
}if( x < 0 AGAIN ){
  console.log("is not okay")
}

I am trying to remove empty space from (dateaxis) xAxis in amchart v5

I am trying to remove empty space from the x-axis in amchart5. But I am not able to do it. I have done the same in amchart4 which was working fine. In v4 I was using (dateAxis.skipEmptyPeriods = true; )to remove empty space and it was working fine but the same is not working in amchart5. Can anyone help?

var data=
    [{
    "Date": "2019-08-16",
    "StockSymbol": "MSFT",
    "Open": 134.88,
    "High": 136.46,
    "Low": 134.72,
    "Close": 136.13,
    "Osc_1VI": 1.800985968,
    "HeatmapTrans": 49.15369259
  },
  {
    "Date": "2019-08-19",
    "StockSymbol": "MSFT",
    "Open": 137.85,
    "High": 138.55,
    "Low": 136.89,
    "Close": 138.41,
    "Osc_1VI": 1.850338609,
    "HeatmapTrans": 48.98744781
  },
  {
    "Date": "2019-08-20",
    "StockSymbol": "MSFT",
    "Open": 138.21,
    "High": 138.71,
    "Low": 137.24,
    "Close": 137.26,
    "Osc_1VI": 1.83817469,
    "HeatmapTrans": 49.3823723
  },
  {
    "Date": "2019-08-22",
    "StockSymbol": "MSFT",
    "Open": 138.66,
    "High": 139.2,
    "Low": 136.29,
    "Close": 137.78,
    "Osc_1VI": 1.883285168,
    "HeatmapTrans": 49.57510018
  },
  {
    "Date": "2019-08-23",
    "StockSymbol": "MSFT",
    "Open": 137.19,
    "High": 138.35,
    "Low": 132.8,
    "Close": 133.39,
    "Osc_1VI": 1.871858131,
    "HeatmapTrans": 49.72754159
  }
];
    

am5.ready(function() {
var root = am5.Root.new("chartdiv");
root.setThemes([
  am5themes_Animated.new(root)
]);

var chart = root.container.children.push(am5xy.XYChart.new(root, {
  panX: true,
  panY: false,
  wheelX: "panX",
  wheelY: "zoomX", 
  layout: root.verticalLayout
}));
var valueAxisRenderer = am5xy.AxisRendererY.new(root, {
  inside: true
});
valueAxisRenderer.labels.template.setAll({
  centerY: am5.percent(100),
  maxPosition: 0.98
});
var valueAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
  renderer: valueAxisRenderer,maxPrecision: 0,
  height: am5.percent(100)
}));
valueAxis.axisHeader.children.push(am5.Label.new(root, {
  text: "Price",
  fontWeight: "bold",
  paddingBottom: 5,
  paddingTop: 5
}));

var dateRenderer = am5xy.AxisRendererY.new(root, {
  inside: true
});
dateRenderer.labels.template.setAll({
  centerY: am5.percent(50),
  maxPosition: 0.98
});
var date = chart.yAxes.push(am5xy.ValueAxis.new(root, {  
  renderer: dateRenderer,
  height: am5.percent(70),
  layer: 5,/*min:0,max:4, strictMinMax: true,*/
  numberFormat: "#a"
}));
date.axisHeader.set("paddingTop", 10);
date.axisHeader.children.push(am5.Label.new(root, {
  text: "Close Price",
  fontWeight: "bold",
  paddingTop: 5,  
  paddingBottom: 5
}));





var dateAxisRenderer = am5xy.AxisRendererX.new(root, {});
dateAxisRenderer.labels.template.setAll({
  minPosition: 0.01,
  maxPosition: 0.99,
  minGridDistance: 30
});
var dateAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
     baseInterval: { timeUnit: "day", count: 1 },
     groupCount: 0,tooltipDateFormat: "MMM d, yyyy",
    renderer: dateAxisRenderer,
    
  
}));
dateAxis.set("tooltip", am5.Tooltip.new(root, {})); 

var color = root.interfaceColors.get("background");
var valueSeries = chart.series.push(
  am5xy.CandlestickSeries.new(root, {
    clustered:false,
    calculateAggregates: true,
    stroke: color,calculateAggregates: true,
    name: "MSFT",
    xAxis: dateAxis,
    yAxis: valueAxis,
    valueYField: "Close",
    openValueYField: "Open",
    lowValueYField: "Low",
    highValueYField: "High",
    valueXField: "Date",
    lowValueYGrouped: "Low",
    highValueYGrouped: "High",
    openValueYGrouped: "Open",
    valueYGrouped: "Close",
    legendValueText: "{StockSymbolValueY} Open: {openValueY} Low: {lowValueY} High: {highValueY} Close: {valueY}",
    legendRangeValueText: "{valueYDate}"
  })
);
    // Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/

var firstColor = chart.get("colors").getIndex(0);

var Osc_1VISeries = chart.series.push(am5xy.ColumnSeries.new(root, {
    name: "",
    xAxis: dateAxis,
  yAxis: date,
   /*valueYField: "Close",*/
    valueYField:"HeatmapTrans",
    valueXField: "Date",
    tooltip: am5.Tooltip.new(root, {
      labelText: "{valueY}"
    })
  })
);



    
    
    
    
Osc_1VISeries.columns.template.setAll({
  strokeOpacity: 0,
  width: am5.percent(100),
  fillOpacity: 1
});


var scrollbar = chart.set(
  "scrollbarX",
  am5xy.XYChartScrollbar.new(root, {
    orientation: "horizontal",
    height: 60
  })
);

var sbDateAxis = scrollbar.chart.xAxes.push(
 am5xy.DateAxis.new(root, {
    groupData: true,
    groupInterval: { timeUnit: "month", count: 1 },
    renderer: am5xy.AxisRendererX.new(root, {})
  })
);

var sbValueAxis = scrollbar.chart.yAxes.push(
  am5xy.ValueAxis.new(root, {
    renderer: am5xy.AxisRendererY.new(root, {})
  })
);

    

    
    
var valueTooltip = valueSeries.set("tooltip", am5.Tooltip.new(root, {
  getFillFromSprite: false,
  getStrokeFromSprite: true,
  getLabelFillFromSprite: true,
  autoTextColor: false,
  pointerOrientation: "horizontal",
  labelText: "{name}: {valueY} {valueYChangePreviousPercent.formatNumber('[#00ff00]+#,###.##|[#ff0000]#,###.##|[#999999]0')}%"
}));
valueTooltip.get("background") .set("fill", root.interfaceColors.get("background"));

var valueLegend = valueAxis.axisHeader.children.push(
  am5.Legend.new(root, {
    useDefaultMarker: true
  })
);
valueLegend.data.setAll([valueSeries]);

var Osc_1VILegend = date.axisHeader.children.push(
  am5.Legend.new(root, {
    useDefaultMarker: true
  })
);
Osc_1VILegend.data.setAll([Osc_1VISeries]);

chart.leftAxesContainer.set("layout", root.verticalLayout);

chart.set("cursor", am5xy.XYCursor.new(root, {}))

var scrollbar = chart.set("scrollbarX", am5xy.XYChartScrollbar.new(root, {
  orientation: "horizontal",
  height: 50
}));

var sbDateAxis = scrollbar.chart.xAxes.push(am5xy.DateAxis.new(root, {
  groupData: true,
  groupIntervals: [{
    timeUnit: "week",
    count: 1
  }],
  baseInterval: {
    timeUnit: "day",
    count: 1
  },
  renderer: am5xy.AxisRendererX.new(root, {})
}));

var sbValueAxis = scrollbar.chart.yAxes.push(
  am5xy.ValueAxis.new(root, {
    renderer: am5xy.AxisRendererY.new(root, {})
  })
);

var sbSeries = scrollbar.chart.series.push(am5xy.LineSeries.new(root, {
  valueYField: "Close",
  valueXField: "Date",
  xAxis: sbDateAxis,
  yAxis: sbValueAxis
}));

sbSeries.fills.template.setAll({
  visible: true,
  fillOpacity: 0.3
});
    
 var processor = am5.DataProcessor.new(root, {emptyAs: 0,
    dateFields: ["Date"],
    dateFormat: "dd-MM-yyyy",
    numericFields: ["Open", "High", "Low", "Close", "HeatmapTrans", "Osc_1VI"]
  });
 
  processor.processMany(data);
  valueSeries.data.setAll(data);
  Osc_1VISeries.data.setAll(data);
  sbSeries.data.setAll(data);
  console.log(data)
 series.data.setAll(data);
    
am5.net.load("data.json").then(function(result) {
  dateAxis.data.setAll(am5.JSONParser.parse(result.response));
}).catch(function(result) {
  console.log("Error loading " + result.xhr.responseURL);
});
chart.appear(1000, 100);
});
#chartdiv {
  width: 100%;
  height: 600px;
  max-width: 100%;
}
    body
    {
        fill:#F4F5F6;
    }

<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<div id="chartdiv"></div>

array.push not working inside a function with preventDefault()

My array.push is not working inside the function with preventDefault()

var correct = [];

function Drop(e){
  e.preventDefault();

 if(e.target.id === "images"){
  correct.push("testID"); //this part is not pushing
  console.log(correct); // it is showing here
  }
}

console.log(correct); // not showing here , its empty

But outside the function , the array is not showing

Anyone encountered this?

How to get the infobox data of Wikipedia?

I am making a website that will automatically get the data from wikipedia using Wikipedia API. What I have already tries is to use find('.infobox') to find the infobox data.

However, I only want to get the data below the horizontal line in the infobox(starting from disease: covid in the photo below)

Here is the code I currently had:

let area = "Canada"
var url="http://en.wikipedia.org/w/api.php?action=parse&format=json&page=COVID-19_pandemic_in_"+area +"&redirects&prop=text&callback=?";
$.getJSON(url,function(data){
     wikiHTML = data.parse.text["*"];
$wikiDOM = $("<document>"+wikiHTML+"</document>");
var info= $wikiDOM.find('.infobox').html();
console.log(info)

This will display all the information in the infobox.

Could anyone give me an idea or a solution that tell me how to do that?

Also, the image from wikipedia will not be able to display which will show error of invalid url (the image area will display alt text) Is there a way to choose not to display image before displaying which will prevent the image (alt text) and error in console ?

Thanks for any responds!

*In the image below, I only want to get the data from disease: Covid-19 to Vaccinations

enter image description here

How to count the number of rendered li items for ul during mapping using MutationObservabl?

I have this issue where I want to know in real-time the number of li element that are getting added to the ul, I am using a custom observer hook the problem is it does not seem to be working.. any idea what I am doing wrong? , I don’t want the number to show when for example if I add to the list I want to implement some logic when the items are getting rendered on load, and if the count reaches for example 10 I want for sake of argument insert a div between the li and the following li.

const listRef = useRef<HTMLUListElement>(null);
  const [count, setCount] = useState(0);
  const onListMutation = useCallback(
    (mutationList) => {
      console.log(mutationList);
      setCount(mutationList[0].target.children.length);
      console.log(mutationList);
    },
    [setCount]
  );

  const DEFAULT_OPTIONS = {
    config: { attributes: true, childList: true, subtree: true },
  };

  const useMutationObservabl = (targetEl: any, cb: any, options: any) => {
    const [observer, setObserver] = useState<any>(null);
    useEffect(() => {
      const { debounceTime } = options;
      const obs = new MutationObserver(cb);
      setObserver(obs!);
    }, [cb, options, setObserver]);

    useEffect(() => {
      if (!observer) return;
      const { config } = options;
      observer.observe(targetEl, config);
      return () => {
        if (observer) {
          observer.disconnect();
        }
      };
    }, [observer, targetEl, options]);
  };

  useMutationObservabl(listRef.current!, onListMutation, DEFAULT_OPTIONS);

  return (
    <div id='Items' style={{ textAlign: 'center' }}>
      itemscol.map(([groupName, items]: Mapped) => (
          <ul
            ref={listRef}
          >
            {Name}
          </ul>
          {items.map((exercise) => (
            <li>
            {Name}
            </li>
          ))}
        </Container>
      ))}
    </div>
  );
};

export default BodyExport;

Javascript equivalent for PHP openssl_encrypt

I have PHP code to encrypt plain string.

base64_encode is used to make the AES-256 encrypted string url-safe.

<?php
echo base64_encode(openssl_encrypt($messageToEncrypt, "AES-256-CBC", $key, true, str_repeat(chr(0), 16)));
?>

I need javascript version of this encrypt code which yields the same result.

Any help will be appriciated.

Thank you!!

Dynamically change the path of an animateMotion SVG element on event

I want to , for a specific event, such as onclick, as a specific SVG element, change that SVG’s animateMotion element and play that animation again. My current code does replay the animation correctly, but does not change the path attribute

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>SVG Example</title>
    <style>
        * { padding: 0; margin: 0; }
    </style>
</head>
<body>


<script>
  window.addEventListener("click", function(e){
    var dot = document.getElementById("reddot");
     dot.path = 'M 0 0 H ' + (e.clientX) + ' V ' + (e.clientY);
     dot.beginElement();
  });
</script>
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">

  <circle cx="0" cy="0" r="2" fill="red">
    <animateMotion dur="5s" id="reddot" repeatCount="1" path="M 0 0 H 10 V 10" restart="always" />
  </circle>
</svg>

</body>
</html>

Clicking multiple times plays the animation multiple times, yet path does not change. The specific goal of this is to create an animation where the animation moves to where the mouse was clicked.