setState does not update children in React

I am building a simple app to visually construct mazes to be solved using different search algorithms. I have a state maze that contains an array of arrays of the states of each block and I pass this to a child Grid which renders the maze from the array. However, whenever I update the state using the function updateMaze(y, x, newState) the maze state is update but the child Grid does not re-render. Why is that?

App.js:

import './App.css';

import Block from './components/Block'
import Row from './components/Row'
import Grid from './components/Grid'
import MazeView from './components/MazeView';

import SideBarItem from './components/SideBarItem';

import New from './assets/new-page.png'
import Checkmark from './assets/checkmark.png'
import Maximize from './assets/maximize.png'
import Random from './assets/random.png'
import Square from './assets/square-measument.png'



import { useState, useEffect } from 'react'

function App() {
  const [size, setSize] = useState({
    width: 15,
    height: 8
  })

  const defaultDimensions = 85

  const [dimensions, setDimensions] = useState(defaultDimensions)
  const [scale, setScale] = useState(1)
  const [MazeViewStyle, setMazeViewStyle] = useState(String())
  const [maze, setMaze] = useState([])

  const [globalW, globalH] = [window.innerWidth * 0.9 - 35, window.innerHeight * 0.85]

  const getAttrib = (columns, rows, defaultDimensions) => {
    let scale = defaultDimensions
    // If there are more columns than rows
    if (columns >= rows) {
      // Sets the scale to fill the height with rows
      scale = globalH / (rows * defaultDimensions)
      // Unless the columns do not fill the entire width of the screen
      if (columns * defaultDimensions * scale < globalW) {
        scale = globalW / (columns * defaultDimensions)
      }
    }
    // In the opposite scenario (rows more than columns)
    if (rows > columns) {
      // Sets the scale to fill the width with columns
      scale = globalW / (columns * defaultDimensions)
      // Unless the rows do not fill the height
      if (rows * defaultDimensions * scale < globalH) {
        scale = globalH / (rows * defaultDimensions)
      }
    }

    // Compute flags
    const flags = {
      centerWidth: columns * defaultDimensions < globalW,
      centerHeight: rows * defaultDimensions < globalH
    }

    // Sets maximum result 1 and minimum 0
    if (scale >= 1) return { scale: 1, flags: flags }
    else if (scale <= 0.1) return { scale: 0.1, flags: {centerWidth: false, centerHeight: false} }
    else return {scale: scale, flags:  {centerWidth: false, centerHeight: false}}
  } 

  const getMazeViewAuxStyle = (flags) => {
    // Unpack a flag
    let [centerWidth, centerHeight] = [flags.centerWidth, flags.centerHeight]
    // If both flags are false return an empty string
    if (!centerWidth && !centerHeight) { return String() }

    // If the columns and rows are not sufficient
    if (dimensions * size.width < globalW && dimensions * size.height < globalH) return "small smallw smallh"

    // Otherwise find the necessary class names
    let style = "small"
    if (centerWidth) style = style + " smallw"
    if (centerHeight) style = style + " smallh"
    return style
  }


  const populateArea = () => {
    // Fetch attributes of the current maze
    const fetchedAttrib = getAttrib(size.width, size.height, defaultDimensions)

    // Update the scale and dimensions
    setScale(fetchedAttrib.scale)
    setDimensions(defaultDimensions * fetchedAttrib.scale)

    // Update flags
    setMazeViewStyle(["maze-view", getMazeViewAuxStyle(fetchedAttrib.flags)].join(" "))

    // Initialize maze space
    initializeMazeSpace(size.height, size.width)
    populateRandom()
    // renderMaze()
  }

  // Populates the maze in the right dimensions
  // only when a new maze is loaded
  useEffect(() => {
    populateArea()
  }, [])

  // Updates the dimensions based on scale
  useEffect (() => {
    setDimensions(defaultDimensions * scale)
  }, [scale])

  const initializeMazeSpace = (rows, columns) => {
    let newMaze = maze
    for (let i = 0; i < rows; i++) {
      newMaze[i] = []
      for (let j  = 0; j < columns; j++) {
        newMaze[i][j] = "empty"
      }
    }
    setMaze(newMaze)
  }

  const updateMaze = (i, j, blockState) => {
    if (maze.length === 0) {
      initializeMazeSpace(size.height, size.width)
    }
    setMaze(() => 
      maze.map((row, a) => 
        i === a ? (row.map((block, b) => b === j ? blockState : block)) : row
      )
    )
  }

  const populateRandom = (height = size.height, width = size.width) => {
    let newMaze = maze
    const classes = ["empty", "wall", "steel"]
    for (let i = 0; i < height; i++) {
      for (let j  = 0; j < width; j++) {
        let pick = classes[Math.floor(Math.random() * 3)]
        newMaze[i][j] = pick
      }
    }
    setMaze(newMaze)
  }

  return (
    <>
      <div className='view'>
        <MazeView style={MazeViewStyle} grid={<Grid scale={scale} maze={maze} defaultDimensions={defaultDimensions} />}/>
        <div className='sidebar'>
          <SideBarItem icon={New} onClick={() => {
            updateMaze(0,0,"steel")
          }}/>
          <SideBarItem icon={Square} onClick={() => console.log(maze)}/>
          <SideBarItem icon={Maximize} onClick={() => setScale(0.5)} />
          <SideBarItem icon={Random} onClick={() => populateRandom()}/>
          <SideBarItem icon={Checkmark} />
        </div>
      </div>
    </>
  );
}

export default App

Grid.js:

import React from 'react'
import Row from './Row'
import Block from './Block'


const Grid = ({ scale, maze, defaultDimensions }) => {
    const renderMaze = () => {
        let mazeComponents = maze.map((row) => {
            return <Row columns={row.map(block =>  (<Block inheritedType={block} dimensions={defaultDimensions * scale} onAction={() => console.log("running")} onDoubleClick={(e, p) => e.target.classList.remove(p)}/>))}/>
        })
        return mazeComponents
    }

    return (
        <div className='grid-view'>
           {renderMaze()}
        </div>
    )
}

export default Grid

Note: setScale triggers a re-render.

is there a way to make it so that an alert doesn’t appear if someone hasn’t answered a previous window.prompt? [duplicate]

So, I was just tinkering around with some javascript, trying to understand it a bit more. I noticed that there is the window.prompt() script. It opens a little space where you can type in something, in the window. Then, there’s also alert().

We also have var, for variables.

so, naturally, placing something as

var y = window.prompt("Some question");

alert("Something " + y);

would allow you to make a “responsive” answer. However, I noticed that if you closed the window.prompt, it still sends you to the alert, and the place where you added your variable will automatically have the world “null” added to it. I want to know if there is any way to stop that.

Something that could work so that if Close was clicked, then the alert wouldn’t appear.

<button onclick="hi()">
    Hi
</button>
<style>
h1 {
    
    color:red
}

button {
    
color:white;
    background:black;
    font-size:60px;
}

button:hover{
    
    color:black;
    background-color:white;
    cursor:pointer;
}
</style>
<script>
function hi() {
    
    var y = window.prompt("What are your favorite crackers?");
    
// I want to make it so that this doesn't show if the above window prompt wasn't answered. Currently, it only shows "null". 

alert("Oooh! " + y + " are my favorite crackers, too!");
}

</script>

How do I make my timeline a lot larger on my page were it still looks good?

I have a horizontal timeline on my website, I want it to be much larger and stand out. I will put the HTML, CSS, and a pic of how it currently works. I also want to change the color to white on the orange line. Text and content on the whole webpage is fairly large.
enter image description here

.timeline {
  padding: 0px;
  width: 800px;
  height: 20px;
  list-style: none;
  text-align: justify;
  margin: 80px auto;
  background: -webkit-gradient(
    left top,
    left bottom,
    color-stop(0%, rgba(255, 255, 255, 0)),
    color-stop(45%, rgba(255, 255, 255, 0)),
    color-stop(51%, rgba(191, 128, 11, 1)),
    color-stop(57%, rgba(255, 255, 255, 0)),
    color-stop(100%, rgba(255, 255, 255, 0))
  );
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0) 45%,
    rgba(191, 128, 11, 1) 51%,
    rgba(255, 255, 255, 0) 57%,
    rgba(255, 255, 255, 0) 100%
  );
}

.timeline:after {
  display: inline-block;
  content: "";
  width: 100%;
}

.timeline li {
  display: inline-block;
  width: 20px;
  height: 20px;
  background: #7597de;
  text-align: center;
  line-height: 1.2;
  position: relative;
  border-radius: 50%;
}

.timeline li:before {
  display: inline-block;
  content: attr(data-year);
  font-size: 26px;
  color: #fff;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

.timeline li:nth-child(odd):before {
  top: -40px;
}
.timeline li:nth-child(even):before {
  bottom: -40px;
}

.timeline li:after {
  display: inline-block;
  content: attr(data-text);
  font-size: 16px;
  color: #fff;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

.timeline li:nth-child(odd):after {
  bottom: 0;
  margin-bottom: -10px;
  transform: translate(-50%, 100%);
}
.timeline li:nth-child(even):after {
  top: 0;
  margin-top: -10px;
  transform: translate(-50%, -100%);
}
<!--StartofTimeline-->
<ul class="timeline">
  <li data-year="2017" data-text="Lorem ipsum dolor sit amet, consectetur."></li>
  <li data-year="2018" data-text="Lorem ipsum dolor sit amet, consectetur."></li>
  <li data-year="2019" data-text="Lorem ipsum dolor sit amet, consectetur."></li>
  <li data-year="2020" data-text="Lorem ipsum dolor sit amet, consectetur."></li>
  <li data-year="2021" data-text="Lorem ipsum dolor sit amet, consectetur."></li>
</ul>
<!--EndofTimeline-->

Thanks in advance for any and all help.

Interview Question: How to calculate if given a maximum CPU, will the job be true or false overtime? [closed]

I have recently failed an interview process due to this interview question: How to calculate if given a maximum CPU, will the job be true or false overtime?

Let’s say if we have a Job class with a constructor with startTime, duration, and cups for this specific job. We need to create a function with a given maxCpus, and see if the jobs will either be possible for the CPU requirement or not, return true or false.

Below is some example of the true and false cases.

Example: maxCpus = 3
0123456789
0---(3) 0--------(2)
  0------------(1) => false

Example: maxCpus = 3
0---3 0--------2 0-------1 => true

Example:
0 1 2 3 4 5 6 7 8 9
    0 - - - (start: 2, duration: 4)
      0 - - (start: 3, duration: 3)

earliest start ---------------- latest end time
jobs = [{startTime: 1, duration: 2, cpus: 5}, {}];
       [{}, {}, {}]

Below is some of the code I wrote for this question, but be aware that my solution is not correct!!!

function checkSchedule(maxCpus, jobs){
 let check;
 for (job in jobs) {
   const earliestStart = Math.min(...Object.values(job.startTime))
   const latestEnd = Math.max(job.startTime + (job.duration - 1))
   let endPoint = job.startTime + (job.duration - 1);
 }
 if(maxCpus <= ){
   check = true
 } else {
   check = false
 }
 return check;
}

I am still not able to figure out the solution to this question.

Get value from json array using javascript

How do get the first name “Niranth” with the following json?

[
 {"firstName":"Niranth","lastName":"Padmonkar","wins":12},
 {"firstName":"Nick","lastName":"Tallent","wins":10}, 
 {"firstName":"Kyle","lastName":"Brisson","wins":5}, 
 {"firstName":"Kyle","lastName":"Brisson","wins":5}
]

Here’s what I have tried.

var data = Http.responseText;
var objects = JSON.parse(data)

document.getElementById("Slot1Name").innerHTML = data[0].firstName;

JavaScript – Drawing a circle/dot with each click depending on the coordinates

I want to be able to paint or draw a circle/dot every time the user clicks inside a rectangle. It should be possible to add as many circles/dots as there are clicks and their position changes depending on the coordinates where the click was made. This is the code I’m using:

Circle:

 <circle cy="50" cx="50" r="30" fill="#f"></circle>

Code:

<!DOCTYPE html>
<html>
<head>
<style>
div {
  width: 200px;
  height: 100px;
  border: 1px solid black;
}
</style>
</head>
<body>

<div onmousemove="showCoords(event)" onmouseout="clearCoor()"></div>

<p>Mouse over the rectangle above to get the horizontal and vertical coordinates of your mouse pointer.</p>

<p id="demo"></p>

<script>
function showCoords(event) {
  var x = event.clientX;
  var y = event.clientY;
  var coor = "X coords: " + x + ", Y coords: " + y;
  document.getElementById("demo").innerHTML = coor;
}

function clearCoor() {
  document.getElementById("demo").innerHTML = "";
}
</script>

</body>
</html>

Code in action: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_event_mouse_clientxy2

What should I add in this code so it does what I want?

Importing vue component into my page Uncaught Exception

I have a page which loads the following JS files

  • Vue.js
  • app.js

The app.js file is compiled using webpack, this includes a NPM component from @chenfengyuan/vue-countdown.

I am trying to display a vue.js countdown component on my page using the following code on my page:

<div class="container" id="app">
    <vue-countdown :time="2 * 24 * 60 * 60 * 1000" v-slot="{ days, hours, minutes, seconds }">
        Time Remainingļ¼š@{{ days }} days, @{{ hours }} hours, @{{ minutes }} minutes, @{{ seconds }} seconds.
    </vue-countdown>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="js/app.js"></script>
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
<script>
    import VueCountdown from '@chenfengyuan/vue-countdown';

    // Vue application
    const app = new Vue({
        el: '#app',
        data: {
            messages: [],
        },
    });
    app.component(VueCountdown.name, VueCountdown);

</script>

When I run this I get a JS error saying:

Uncaught SyntaxError: Cannot use import statement outside a module

Can someone explain what I am doing wrong and how I can correctly import this?

Jquery on client side with nodejs server

I use nodejs (in a docker-compose container, not sure if that is relevant) to set up a local web app. I would like to use jquery on the client-side to load an HTML file into a div. Unfortunately, it is not working. The initial index.html and the new.html are in the same folder (/frontend/). What am I missing?

Nodejs app:


var app = express();

// home route returns rendered html content
app.get("/", (req, res) => {
  res.sendFile(__dirname + "/frontend/index.html");
});

app.listen(3000, function(){
    console.log('Example app listening on port 3000!');
});

index.html:

<!DOCTYPE html>
<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
            crossorigin="anonymous">
        </script>
        
        <script type="text/javascript">
            $(document).ready(function(){
                $("#imported").load("new.html");
            });
        </script>
    </head>
    <body>
        <div> This is content of the index HTML and below is the imported HTML:</div>
        
        <div id="imported"></div>
    </body>
</html>

Lastly the HTML I want to import new.html:

<HTML>
  <head>
  </head>
  <body>
    <p>This is demo text.<p>
  </body>
</html>

How to extract a JSON value from a node.js “request-promise” https query? The request-promise syntax itself appears problematic

I’m running my javascript code with node.js and am using the request-promise library to generate https requests which return a json blob. So far, I’ve managed to send the request correctly–and I do receive the desired json object in the response, but I’m only seeing the keys, not the values. I want to extract the value for a key called “call_count”. The problem I’m facing is the peculiar structure of the request-promise syntax, which appears to be preventing me from doing what I want to do.

Here’s what the JSON response looks like when I run my query in Postman:

{
  "metric_data": {
    "from": "2021-12-12T23:56:12+00:00",
    "to": "2021-12-13T00:26:12+00:00",
    "metrics_not_found": [],
    "metrics_found": [
        "Mobile/Crash/All"
    ],
    "metrics": [
        {
            "name": "Mobile/Crash/All",
            "timeslices": [
                {
                    "from": "2021-12-12T23:53:00+00:00",
                    "to": "2021-12-13T00:23:00+00:00",
                    "values": {
                        "call_count": 0
                    }
                }
            ]
        }
    ]
  }
}

And here’s my code that generates the request:

const rp = require ('request-promise');

let options = {
  method: 'GET',
  uri: 'https://api.crashCatcher.com/v2/mobile_applications/myAppID/metrics/data.json?names=Mobile/Crash/All&values[]=call_count&summarize=true',
  headers: {
    'User-Agent': 'request-promise',
    'X-Api-Key': 'MY API key goes here'
  },
  json: true // Automatically parses the JSON string in the response
};

rp(options).then(body => console.log(body)).catch(err => console.log(err.name, err.statusCode));

Currently, when I run this code, here’s what I’m getting back:

{ metric_data: 
   { from: '2021-12-13T00:22:04+00:00',
     to: '2021-12-13T00:52:04+00:00',
     metrics_not_found: [],
     metrics_found: [ 'Mobile/Crash/All' ],
     metrics: [ [Object] ] } }

Now, I know I’m getting a JSON object back, and I know I need to do something like:

var myJson = JSON.parse(*body*);

And then something like:

console.log(myJson.metric_data.metrics[0].timeslices[0].values.call_count);

But when using the request-promise syntax, I don’t know how to correctly assign what’s coming back in my response body to a variable that I can then JSON.parse and extract the needed call_count value from.

Node JS – Check if string is a directory

How to check if a string is a directory? I tried casting and using .isDirectory(), not working for me.
Also tried something like this:

let dirs = input.filter(dir => fs.openSync(dir));

but, of course, i get an error when I pass common string. I tried wrapping it into try-catch, didn’t work.

How to export three database tables into one single sheet using datatables?

The website is in Php. I am using datatables.net to export my database table. But, it works fine for one table. But, I have three tables on a web page. How can I export all those three tables into one sheet? Please help.

Script:

<script>
$(document).ready(function() {
    $('#table1').DataTable( {
        dom: 'Bfrtip',
        buttons: [
            'copy', 'csv', 'excel', 'pdf', 'print'
        ]
    } );
} );


</script>

How to change a className of a particular element based off it’s child input value and input dataset comparison?

It’s my first time posting – hello everyone!

I’m making an app that’s going to help me memorize geographical data.

I have a map with markers on it, when I click on any of these markers a popup appears in which I have an input. I’m comparing the input value with input dataset to see if my answer was correct or not. The thing is, I would also like to change the color of the marker (ImageOverlay) to green as soon as my answer is correct and red if it’s wrong (as soon as any value appears).

The main problem I have is that those markers are mapped from an object which is fetched from firebase, meaning that every single input has to change the color of the corresponding marker and that marker only.

I hope I explained it clearly. Thank you so much in advance!

displayPins that maps data from a firebase doc:

 const displayPins = doc.map((d) => {
return (
  <ImageOverlay
    className="img-overlay"
    key={d.id}
    bounds={[
      [d.latitude - 2, d.longitude - 2],
      [d.latitude + 2, d.longitude + 2],
    ]}
    interactive={true}
    url={`./${d.shape}`}
  >
    <Popup>
      <input type="text" data-tag={d.name} onChange={valueCompare}></input>
      <button
        onClick={() => {
          console.log(test);
        }}
      ></button>
    </Popup>
  </ImageOverlay>
);});

Input’s onChange:

const valueCompare = (e) => {
const data = e.target.dataset.tag;
const value = e.target.value;
if (data != value) {
  console.log("WRONG");
} else {
  console.log("CORRECT");
}};

CSS

.img-overlay {
  filter: brightness(0) saturate(100%);
}
.img-overlay-wrong {
  filter: invert(10%) sepia(95%) saturate(7496%) hue-rotate(11deg)
    brightness(97%) contrast(120%);
}
.img-overlay-correct {
  filter: invert(69%) sepia(61%) saturate(4725%) hue-rotate(78deg)
    brightness(112%) contrast(128%);
}

Should I getElementById on button click or on page load? [closed]

Pretty much what the title states, I am debating without much experience if I should getElementId on click or as a global var when the page loads.

So, it’s either this:

var cp1 = document.getElementById('cp1');
var olp = document.getElementById('olp');

ob.addEventListener("click", func_ob);
function func_ob() {
  cp1.classList.add('hidden');
  olp.classList.remove('hidden');
}

Or this:

ob.addEventListener("click", func_ob);

function func_ob (element1, element2) {
  document.getElementById(element1).add('hidden');
  document.getElementById(element2).remove('hidden');
}

If I had to make a guess, I would say this is loading time vs run time? I’m not sure, I could really use someone more experienced to break it down for me a bit.

Thanks in advance!

How to update code to have Error-First callback in Nodejs?

This Code is for a simple Traffic Light, now when running it on the Beaglebone black I receive the warning:”warning: single argument callbacks will be deprecated.please use node-style error-first callbacks: callback(err,response)”. I am unsure of how do do what its asking in my code any help would be appreciated.

var b = require('bonescript');

var red = "p8_13";
var yellow = "p8_15";
var green = "P8_17";
var inputPin = "P8_10";

var switchstatus =0;

b.pinMode(red,b.OUTPUT);
b.pinMode(yellow,b.OUTPUT);
b.pinMode(green,b.OUTPUT);
b.pinMode(inputPin,b.OUTPUT);

var on = b.HIGH;
var off = b.LOW;

setInterval(check,200);

function check(){
    b.digitalRead(inputPin, checkButton);
    }

function checkButton(x){
    if (x.value == 1){
        switchstatus++;
        switch (switchstatus){
            case 1: setTimeout(function
              (){b.digitalWrite(red,on);
                 b.digitalWrite(yellow,off);
                 b.digitslWrite(green,off);},500);
            break;
        case 2: setTimeout (function
              (){b.digitalWrite(yellow,on);},500);
             break;
        case 3: setTimeout (function
              (){b.digitalWrite(red,off);
            b.digitalWrite(green,on);},500);
             break;
        case 4: setTimeout (function
              (){b.digitalWrite(yellow,on)
                 b.digitalWrite(green, on);},500);
             break;
            default: swtchstatus = 0;
            break;
        }
        }
        else if (switchstatus >=5){
            switchstatus = 0;
            callback(err,response);
            }
        }