Why HTML page is not generating and not requested for a, supposedly, SSG page in NextJS app?

I have a static route page, say myPage, that I want to be statically generated during build time as SSG.
When I run the build I see that myPage is marked as SSG in console.
On my local I do not see myPage.html but myPage.js inside .next/server/.
Also when I open that page in browser I do not see a document type request for myPage instead I see requests for a json and js file.
What could be wrong? myPage is a static route and I am using getStaticProps with revalidate: 100 * 10

I have this error in Tic tac Toe game Uncaught TypeError : Cannot read properties of undefined ( reading ‘0’ )

This is my code
Can anyone tell me why I have
This error

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

document.addEventListener('DOMContentLoaded', function () {
  const board = document.getElementById('board');
  const resetBtn = document.getElementById('resetBtn');
  const message = document.getElementById('message');

  let currentPlayer = 'X';

  let gameActive = true;

  let boardState = ['', '', '', '', '', '', '', '', ''];

  function makeMove(index) {
    if (boardState[index] === '' && gameActive) {
      boardState[index] = currentPlayer;

      renderBoard();

      checkWinner();

      currentPlayer = currentPlayer === 'X' ? 'O' : 'X';

      if (currentPlayer === 'O' && gameActive) {
        makeComputerMove();
      }
    }
  }

  function makeComputerMove() {
    let bestScore = -Infinity;

    let bestMove;

    console.log('boardState before making moves:', boardState);

    for (let i = 0; i < boardState.length; i++) {
      if (boardState[i] === '') {
        boardState[i] = 'O';

        console.log('boardState after making move:', boardState);

        let score = minimax(boardState.slice(), 0, false); // Pass a copy of the boardState array

        boardState[i] = '';

        if (score > bestScore) {
          bestScore = score;

          bestMove = i;
        }
      }
    }

    makeMove(bestMove);
  }

  function minimax(board, depth, isMaximizing) {
    console.log('minimax called with board:', board);

    let result = checkWinner(board);

    console.log('checkWinner result:', result);

    if (result !== null) {
      return scores[result];
    }

    if (isMaximizing) {
      let bestScore = -Infinity;

      for (let i = 0; i < board.length; i++) {
        if (board[i] === '') {
          board[i] = 'O';

          let score = minimax(board.slice(), depth + 1, false);

          board[i] = '';

          bestScore = Math.max(score, bestScore);
        }
      }

      console.log('maximizing bestScore:', bestScore);

      return bestScore;
    } else {
      let bestScore = Infinity;

      for (let i = 0; i < board.length; i++) {
        if (board[i] === '') {
          board[i] = 'X';

          let score = minimax(board.slice(), depth + 1, true);

          board[i] = '';

          bestScore = Math.min(score, bestScore);
        }
      }

      console.log('minimizing bestScore:', bestScore);

      return bestScore;
    }
  }

  function checkWinner(board) {
    const winConditions = [
      [0, 1, 2],

      [3, 4, 5],

      [6, 7, 8],

      [0, 3, 6],

      [1, 4, 7],

      [2, 5, 8],

      [0, 4, 8],

      [2, 4, 6],
    ];

    for (let condition of winConditions) {
      const [a, b, c] = condition;

      if (board[a] !== '' && board[a] === board[b] && board[a] === board[c]) {
        gameActive = false;

        return board[a];
      }
    }

    if (!board.includes('')) {
      gameActive = false;

      return 'tie';
    }

    return null;
  }

  function renderBoard() {
    board.innerHTML = '';

    boardState.forEach((cell, index) => {
      const cellElement = document.createElement('div');

      cellElement.classList.add('cell');

      cellElement.innerText = cell;

      cellElement.addEventListener('click', () => makeMove(index));

      board.appendChild(cellElement);
    });
  }

  function resetBoard() {
    currentPlayer = 'X';

    gameActive = true;

    boardState = ['', '', '', '', '', '', '', '', ''];

    renderBoard();

    message.innerText = '';
  }

  resetBtn.addEventListener('click', resetBoard);

  const scores = {
    X: -10,

    O: 10,

    tie: 0,
  };

  renderBoard();
});

I want to make a Tic Tac Toe game playing with smart computer but I can’t solve this error

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

Please help and rewrite the correct code

rouble Displaying Weather Data in HTML/JavaScript (displayWeather Error)

let weather= {
    apiKey:"a5fd20552e868ea7597dd68dec1dd543",
    fetchWeather:function(city){
        fetch("https://api.openweathermap.org/data/2.5/weather?q="
        + city 
        + "&units=metrics&appid="
        + this.apiKey
        )
        .then((response)=>response.json())
        .then(data=> displayWeather(data));
    },
    //grabs the data from the api and stores it to a variable for disply sing the corresponding key from the file 
    displayWeather: function(data){
        const name=data;
        const desc = data.weather[0].description;
        const icon= data.weather[0].icon;
        const temp = data.main.temp;
        const speed =data.wind.speed;
        const humidity=data.main.humidity;
        console.log(name,icon,description,temp,speed,humidity);
        document.querySelector(".city").innerHTML = "Weather in " + name;
        document.querySelector(".icon").src = "https://openweathermap.org/img/wn/" +icon+".png";
        document.querySelector.innerText= description;
    


        
    },
}
body{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background: #222;
    font-family: sans-serif;
    background-image: url('https://source.unsplash.com/random/?city,night');
    font-size: 120%;
}


.card{
    background: #000000d0;
    color: white;
    padding: 2em;
    border-radius: 2em;
    width: 100%;
    max-width:420%;
    margin: 1em;
}

.search{
    display: flex;
    align-items: center;
    justify-content: center;
}button {
    border: none;
    margin: 0.5em;
    border-radius: 50%;
    height: 46px;
    width: 46px;
    background: #7c7c7c2b;
    color: white;
    cursor: pointer;
    transition: 0.2s ease-in-out;
}

input.search-bar {
    border: none;
    outline: none;
    padding: .5em 1em;
    border-radius: 24px;
    background: #7c7c7c2b;
    color: white;
    font-family: inherit;
    font-size: 120%;
}



button:hover {
    background: #7c7c7c6b;
}   body{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background: #222;
    font-family: sans-serif;
    background-image: url('https://source.unsplash.com/random/?city,night');
}


.card{
    background: #000000d0;
    color: white;
    padding: 2em;
    border-radius: 2em;
    width: 100%;
    max-width:420%;
    margin: 1em;
}

.search{
    display: flex;
    align-items: center;
    justify-content: center;
}button {
    border: none;
    margin: 0.5em;
    border-radius: 50%;
    height: 46px;
    width: 46px;
    background: #7c7c7c2b;
    color: white;
    cursor: pointer;
    transition: 0.2s ease-in-out;
}

input.search-bar {
    border: none;
    outline: none;
    padding: .5em 1em;
    border-radius: 24px;
    background: #7c7c7c2b;
    color: white;
    font-family: inherit;
    font-size: 120%;
    width: calc(100% - 80px);
}

h1.temp{
    margin: 0;
}



button:hover {
    background: #7c7c7c6b;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather App</title>
    <link rel="stylesheet" href="weather.css">
    <script src="./weather.js"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@1,300&display=swap" rel="stylesheet">
</head>
<body>
    <div class="card">
        <div class="search">
            <input type="text" class="search-bar" placeholder="Search">
            <button><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="1.5em" width="1.5em" xmlns="http://www.w3.org/2000/svg"><path d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"></path></svg></button>
        </div> 
        <div class="weather">
            <h2 class="city">Denver</h2>
            <h1 class="temp">51° C</h1>
            <img src="" alt="" srcset=""class="icon">
            <div class="description">Cloudy</div>
            <div class="humidity">Humidity: 60%</div>
            <div class="wind">Wind speed: 6.2 km/h</div>

        </div>
    </div>
</body>
</html>

I

json file

I’m currently working on a weather app using HTML and JavaScript, where I retrieve weather data from the OpenWeatherMap API and display it in my HTML document. However, I’m encountering an issue with the displayWeather function, which is responsible for updating the DOM elements with the weather information. and i am getting an error reading the”the data for weather.description is ‘0’”
heres my code line 15 of the js file is giving me the problem

json file

Odoo 15 javascript custom button at POS show TypeError is not a function

I want to add custom button at POS product screen which confirm order and render the related QWEB and download it as pdf file into certain folder. However when i try to click the button an error message show “TypeError: order.has_changes_to_print is not a function onClick@https://167.172.87.114/web/assets/504-1c680be/point_of_sale.assets.min.js:5345:63”.
enter image description here
Can anyone help me what does the error mean ? And how to solve it ?
Thanks

Here is my code for the custom button.

odoo.define('pos_enhancement.ConfirmOrderButton', function(require) {
    'use strict';

    const PosComponent = require('point_of_sale.PosComponent');
    const ProductScreen = require('point_of_sale.ProductScreen');
    const { useListener } = require('web.custom_hooks');
    const Registries = require('point_of_sale.Registries');

    class ConfirmOrderButton extends PosComponent {
        constructor() {
            super(...arguments);
            useListener('click', this.onClick);
            this._currentOrder = this.env.pos.get_order();
            this._currentOrder.orderlines.on('change', this.render, this);
            this.env.pos.on('change:selectedOrder', this._updateCurrentOrder, this);
        }
        willUnmount() {
            this._currentOrder.orderlines.off('change', null, this);
            this.env.pos.off('change:selectedOrder', null, this);
        }
        async onClick() {
            const order = this.env.pos.get_order();
            if (order.has_changes_to_print()) {
                const isPrintSuccessful = await order.print_changes();
                if (isPrintSuccessful) {
                    order.saveChanges();
                } else {
                    await this.showPopup('ErrorPopup', {
                        title: this.env._t('Printing failed'),
                        body: this.env._t('Failed in printing the changes in the order'),
                    });
                }
            }
        }
        get addedClasses() {
            if (!this._currentOrder) return {};
            const changes = this._currentOrder.has_changes_to_print();
            return {
                highlight: changes,
            };
        }
        _updateCurrentOrder(pos, newSelectedOrder) {
            this._currentOrder.orderlines.off('change', null, this);
            if (newSelectedOrder) {
                this._currentOrder = newSelectedOrder;
                this._currentOrder.orderlines.on('change', this.render, this);
            }
        }
    }
    ConfirmOrderButton.template = 'ConfirmOrderButton';

    ProductScreen.addControlButton({
        component: ConfirmOrderButton,
        condition: function() {
            return this.env.pos.config.iface_confirmorder;
        },
    });

    Registries.Component.add(ConfirmOrderButton);

    return ConfirmOrderButton;
});

Here is my pos.js file where i define the function

odoo.define('pos_enhancement.pos', function(require) {
    "use strict";

    var models = require('point_of_sale.models');

    var QWeb = core.qweb;

    // var _super_order = models.Order.prototype;
    models.PosModel = models.PosModel.extend({
        get_table_url: async function () {
            var table_url = this.rpc({
                    model: 'restaurant.table',
                    method: 'get_table_url',
                    args: [this.table.id],
                });
            return table_url;
        }
    });

    var _super_order = models.Order.prototype;
    models.Order = models.Order.extend({
        export_for_printing: function() {
            var result = _super_order.export_for_printing.apply(this,arguments);
            const codeWriter = new window.ZXing.BrowserQRCodeSvgWriter();
            var url = this.qr_url || 'undefined';
            let table_qr_code_svg = new XMLSerializer().serializeToString(codeWriter.write(url, 150, 150));
            result.table_qr_code = "data:image/svg+xml;base64," + window.btoa(table_qr_code_svg);
            return result;
        },
        print_changes: async function() {
            let isPrintSuccessful = true;
            var changes = this.computeChanges(this.iface_available_categ_ids);
            if ( changes['new'].length > 0 || changes['cancelled'].length > 0){
                var receipt = QWeb.render('OrderChangeReceipt',{changes:changes, widget:this});
                // const result = await printers[i].print_receipt(receipt);
                // if (!result.successful) {
                //     isPrintSuccessful = false;
                // }
            }
            return isPrintSuccessful;
        },
        has_changes_to_print: function() {
            var changes = this.computeChanges(this.iface_available_categ_ids);
            if ( changes['new'].length > 0 || changes['cancelled'].length > 0){
                return true;
            }
            return false;
        },
    });
});

I tried the same method for submit button which is provided in odoo already, doing exactly the same way but with different function code. However the function that i added did not work.

How to cancel an async operation properly in React / TypeScript?

I have this to check if my server is alive, polling every 10 seconds for a max of 10 times to see if it’s alive.

const wait = (ms: number) => new Promise((res) => setTimeout(res, ms));

export async function checkRemote(
  { maxAttempts = 10 }: { maxAttempts: number } = { maxAttempts: 10 }
) {
  let i = 1;
  while (true) {
    const res = await fetch(`/check`);
    if (res.status >= 400) {
      if (i === maxAttempts) {
        throw new Error("Check failed");
      } else {
        i++;
        await wait(10000);
        continue;
      }
    } else {
      const json = await res.json();
      return json;
    }
  }
}

How can I properly “cancel” this polling in the context of React.js?

The problem is, my checkRemote function is going to continue to execute after my React component unmounts… If it unmounts while the calls are still ongoing.

First of all, the call to checkRemote must be made in a useEffect hook, not as the result of a button click? Or can we make it occur on button click (that would be ideal IMO), but still make it cancelable if they unmount the current component?

useEffect(() => {
  const promise = checkRemote({ maxAttempts: 10 })
    .then(res => {
      setStatus('ready')
    }).catch(e => {
      setStatus('unvailable')
    })

  return () => {
    // on unmount, do something like this?
    promise.abort()
  }
})

Or perhaps for button click:

const [checkPromise, setCheckPromise] = useState<Promise>()

const handleClick = () => {
  const promise = checkRemote({ maxAttempts: 10 })
    .then((res) => {
      setStatus("ready");
    })
    .catch((e) => {
      setStatus("unvailable");
    });
  
  setCheckPromise(promise)
}

useEffect(() => {
  return () => checkPromise.abort()
}, [checkPromise])

return <button onClick={handleClick}>Click me</button>

How could I architect this to pass in the “promise abort handler” into my nested functions? Something like AbortController….

const wait = (ms: number, { controller }) => {
  return new Promise((res) => {
    let timer = setTimeout(res, ms)

    controller.on('abort', () => {
      clearTimeout(timer)
      // to respond or not respond then?
      res()
    })
  })
}

export async function checkRemote(
  { maxAttempts = 10, controller }: { maxAttempts: number } = {
    maxAttempts: 10,
  }
) {
  let i = 1;
  while (!controller.aborted) {
    const res = await fetch(`/check`, { signal: controller });
    if (res.status >= 400) {
      if (i === maxAttempts) {
        throw new Error("Check failed");
      } else {
        i++;
        // somehow stop the timer early if we abort
        await wait(10000, { controller });
        continue;
      }
    } else {
      const json = await res.json();
      return json;
    }
  }
}

If I go down this rabbit hole, what are your recommendations? How do I architect the system to abort every function “properly”? I would probably use a custom event emitter to do this I’m guessing, so I can have controller.on('abort') easily throughout.

What I don’t want to happen is my 10 second * 10 attempt = ~2 minute checker continues to check when the component is unmounted, that would be painful and confusing. I would like for it to cancel everything on unmount basically.

Note: the general problem is how to setup async aborting, not to useContext or something for this specific use case.

how to do proper sentiment analysis with openAi api?

Im building an js app that allows you to create AI based presentations and now the only problem left is creating a design for presentations, what i want to do, is to detect emotional component of the input, then compare it to colors ( for example if text is sad itll be dark blue), and then use this color as a base for my presentation design. I think this can be done with gpt embeddings, but im not sure. I need a spectrum of emotions as output(more then just negative, positive and neutral)
Also if you know any other free solution id be very glad to hear them

Error: Schema validation failed with the following errors: Data path “” must NOT have additional properties(buildTarget)

I’m trying to initialize my angular application where I recently added ng-matero. Given this, I started using the npm run hmr command, but every time I try it always gives the same error. I looked in some places and saw that running the commands npm i @angular-devkit/[email protected] --force and npm i @angular/cli@16 could solve my problem, but that didn’t work either.

This is a copy of my package.json:

    {
  "name": "manager-front-end-v3.1",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "build:prod": "ng build --prod",
    "lint": "npm run lint:ts && npm run lint:scss",
    "lint:ts": "eslint "src/**/*.ts" --fix",
    "lint:scss": "stylelint "src/**/*.scss" --fix",
    "hmr": "ng serve --hmr --disable-host-check"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^16.0.0",
    "@angular/cdk": "^17.1.0",
    "@angular/common": "^16.0.0",
    "@angular/compiler": "^16.0.0",
    "@angular/core": "^16.0.0",
    "@angular/forms": "^16.0.0",
    "@angular/material": "^17.1.0",
    "@angular/material-moment-adapter": "^17.1.0",
    "@angular/platform-browser": "^16.0.0",
    "@angular/platform-browser-dynamic": "^16.0.0",
    "@angular/router": "^16.0.0",
    "@ng-matero/extensions": "^17.0.0",
    "@ng-matero/extensions-moment-adapter": "^17.0.0",
    "@ngx-formly/core": "^6.2.0",
    "@ngx-formly/material": "^6.2.0",
    "@ngx-translate/core": "^15.0.0",
    "@ngx-translate/http-loader": "^8.0.0",
    "moment": "^2.29.4",
    "ng-matero": "^17.0.0",
    "ngx-permissions": "^16.0.1",
    "ngx-progressbar": "^11.1.0",
    "ngx-toastr": "^18.0.0",
    "photoviewer": "^3.9.2",
    "rxjs": "~7.8.0",
    "screenfull": "^6.0.2",
    "tslib": "^2.3.0",
    "zone.js": "~0.13.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^16.0.3",
    "@angular-eslint/builder": "^17.2.0",
    "@angular-eslint/eslint-plugin": "^17.2.0",
    "@angular-eslint/eslint-plugin-template": "^17.2.0",
    "@angular-eslint/schematics": "^17.2.0",
    "@angular-eslint/template-parser": "^17.2.0",
    "@angular/cli": "~16.0.3",
    "@angular/compiler-cli": "^16.0.0",
    "@types/jasmine": "~4.3.0",
    "@typescript-eslint/eslint-plugin": "^6.19.0",
    "@typescript-eslint/parser": "^6.19.0",
    "eslint": "^8.56.0",
    "jasmine-core": "~4.6.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.0.0",
    "parse5": "^7.1.2",
    "prettier": "^3.2.4",
    "stylelint": "^16.1.0",
    "stylelint-config-recess-order": "^4.4.0",
    "stylelint-config-recommended-scss": "^14.0.0",
    "stylelint-config-standard": "^36.0.0",
    "typescript": "~5.0.2"
  }
}

If you need it, this is the github link: https://github.com/Galleazzo/Manager-Front-End-V3.1

I’m just trying to start the project to start developing. I already changed @angular-devkit/build-angular” but nothing happened. I want the project to initialize

How can I get more accurate coordinates from my address for my firebase realtime database [closed]

I am using this URL to get coordinates based on Address, City, State and ZipCode.

var url = "https://nominatim.openstreetmap.org/search?format=json&limit=3&q="
            + busStreetAdr.value + "+" + busCity.value + "+" + busState.value + "+" + busZip.value;

Everything is working as intended. However, I found an address and location that is incorrect. Even if I manually go to the site above it gives me the wrong location.
Is there a better way/URL to get the coordinates?

How to wrap the VideoOverlay component in react-leaflet with additional sibling div for arrow display?

I’m currently working on integrating a video overlay onto a map using the react-leaflet library. I’m using the VideoOverlay component provided by react-leaflet to render the video onto the map successfully. However, I also need to display an arrow pointing from the video to a specific location on the map.

The challenge I’m facing is that the VideoOverlay component only renders the video HTML element, and I’m unsure how to add a sibling div alongside it to display the arrow.

Is there a way to wrap the VideoOverlay component in a containing div and add another sibling div for displaying the arrow? Alternatively, is there a recommended approach or workaround to achieve this functionality while using react-leaflet?

Any guidance on how to accomplish this would be greatly appreciated. Thank you! I am having a go at creating a custom component using the factory methods in the react-leaflet core API

javascript create an object by searching for fields and values using regular expressions

I hope you can help me solve this problem. I need to search for fields and values within a text and turn them into an object.

Example of text

<@if VERSION = "A1">

<@assign CTA = "blue">
<@assign CTA2 = "green">

<@elseif VERSION = "A2">

<@assign CTA = "red">
<@assign CTA2 = "yellow">

</@if>


<@if VERSION = "A3">

<@assign CTA = "brown">
<@assign CTA2 = "grey">

</@if>

I cannot put values belonging to the same field inside the same object. the result I get is that multiple objects with the same field are created.

desired output

[
 { VERSION : 
   [
    { A1:
     [
      { CTA: 'blue',
        CTA2: 'green',
      },
      A2:
     [
      { CTA: 'red',
        CTA2: 'yellow',
      },
      A3:
     [
      { CTA: 'brown',
        CTA2: 'grey',
      },
     ],
    },
  ],
 },
]

I need to search for fields and values within a text and turn them into an object. I cannot put values belonging to the same field inside the same object. the result I get is that multiple objects with the same field are created.

Adjusting tick length and stroke weight for scales in D3.js

I am interested in changing my scale in d3 so there are some ticks that aren’t as long as others.
Similar to a ruler, I only want integers to be labeled and I want ticks representing decimals to be shortened.

Here is a mockup of the effect I am seeking done in Illustrator.
a mockup of the effect I am seeking

Here is my code so far that has allowed me to label only the integers. The tickSize tool doesn’t seem to support variables.

var yAxis = d3.axisRight(y)
    .ticks(10)
    .tickSize(30)
    .tickFormat(function (d) {
        return d % 1 === 0 ? d + "°C" : "";
    });

Also, I am not sure how to make the stroke weight of the ticks thicker.

Generate web build of a rust binary

I’m building a rust project and I want to let user export certain things as .wasm so that they can upload them on their hosting service and let people run it from browser. In order to run it from browser nicely, I have built a separate js project with all the directories and config in place.

Currently, the user needs to run a command which generates .wasm, place the generated binary into certain place and name it certain way, change several variables inside json config files, for example name, description, author etc., and then upload the directory and its content to their hosting service.

I want to make all this automatic, since it’s not a nice user experience to do these things manually.

What’s a good practice for doing this? I’m thinking about using either js or bash scripts for file manipulation and fs things like copying files and folders. I’m not sure if rust is good for this type of thing since I started using it just recently, but from my experience with other low level languages I would say it’s wouldn’t be the best option.

Using the For Loop alongside Rest Parameters

Having a complete and utter brain fart here

Why are we doing sum = sum + numbers[i].

I’ve even looked at the result if we do sum = numbers[i] or sum = sum + numbers and for the life of me can’t figure it out.

Any help would be appreciated

const add = function (...numbers) {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) sum += numbers[i];
  console.log(sum);
};

add(2, 3);
add(5, 3, 7, 2);
add(8, 2, 5, 3, 2, 1, 4);

How to use a promise-based (non-event-emitter) approach to streaming data?

I want to basically do this when I call a function in my app (frontend):

  1. Upload a file. Update progress percent in UI.
  2. Create job and return “Job started” in UI.
  3. Poll job and wait for it to finish.
  4. Return response (converted file in this case).

The UI will basically go through this sequence:

  1. Uploading… (with percentage circle updating)
  2. Queued…
  3. Processing…
  4. Complete

All from calling one function.

The function will use XMLHttpRequest upload progress functionality, like here. It will then poll on the backend using fetch to get the job status. Finally when the job returns “complete”, it will fetch and return the converted file.

What is a proper way of doing that with a promise-based (non event-emitter) approach? Generators?

async function *performUploadJob() {
  const workId = yield await upload(getFile())
  yield { type: 'processing' }
  const output = await pollForJobComplete(workId)
  yield { type: 'result', output }
}

async function pollForJobComplete(workId) {
  while (true) {
    const res = await fetch(`/work/${workId}`)
    const json = await res.json()
    if (json.status === 'complete') {
      return json.output
    }
    await wait(2000)
  }
}

function *upload(file) {
  var fd = new FormData();
  fd.append("file", file);

  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/upload", true);
  xhr.upload.onprogress = function(e) {
    var percentComplete = Math.ceil((e.loaded / e.total) * 100);
    yield { type: 'update', percentComplete }
  };

  xhr.onload = function() {
    if(this.status == 200) {
      yield { type: 'update', percentComplete: 100 }
    }
  }

  xhr.send(fd);
}

Is something like that possible (pseudocode)?

If so, how would you structure it? If not, what would you do instead?

The goal is to be able to just do something like this:

const iterator = performUploadJob()

for (const data of iterator) {
  switch (data.type) {
    ...
  }
}

Javascript code does not work within nested modules in Shiny R

This question is a follow-up to my previous question which was answered.

Goal

Enable handwriting to text conversion in a shiny app while using nested modules.

This works

Three files are relevant:

  • handwriting_for_shiny2.js (placed in www folder)
  • mod_handwriting.R (placed in R folder; this is a module that utilizes the js function)
  • app.R (placed in main app folder)

Running app.R shows a canvas where you can write with a stylus and it is converted to text when the “Send” button is clicked. There also Undo, Redo, and Clear canvas buttons.

This does not work

I then introduced another module (mod_simple.R) that utilizes the module mod_handwriting.R. Then I created another app file called app2.R where I used the mod_simple.R. But this time the buttons don’t work. Although, I can still write in the canvas.

Code

Here is all the code:
handwriting_for_shiny2.js

$(document).ready(function() {
   var handwritingCanvas = {};

  Shiny.addCustomMessageHandler("initialize", function(id) {
    var canvas = document.getElementById(id + '-handwritingCanvas');
    handwritingCanvas[id] = new handwriting.Canvas(canvas, 3);

     // Enable undo and redo
     handwritingCanvas[id].set_Undo_Redo(true, true);
     console.log("This is initialize function");
  });

  Shiny.addCustomMessageHandler("clearCanvas", function(id) {
    handwritingCanvas[id].erase();
    console.log("This is clearCanvas function");
  });

   Shiny.addCustomMessageHandler("undoCanvas", function(id) {
    handwritingCanvas[id].undo();
  });

   Shiny.addCustomMessageHandler("redoCanvas", function(id) {
    handwritingCanvas[id].redo();
  });


  Shiny.addCustomMessageHandler("sendCanvas", function(id) {
    var trace = handwritingCanvas[id].trace;
    var options = {
      language: 'en',
      numOfReturn: 1
    };
    var callback = function(result, err) {
      if (err) {
        console.error(err);
      } else {
        Shiny.setInputValue(id + '-recognized_text', result[0]);
      }
    };
    handwriting.recognize(trace, options, callback);
  });





});

mod_handwriting.R

handwritingUI <- function(id) {
  ns <- NS(id)
  fluidRow(
    column(
      width = 4,
      actionButton(ns("clear_canvas"), "Clear Canvas"),
      actionButton(ns("undo"), "Undo"),
      actionButton(ns("redo"), "Redo"),
      actionButton(ns("send"), "Send"),
      textAreaInput(ns("manual_text"), "Enter Text", value = ""),
      tags$canvas(id = ns("handwritingCanvas"), width = "400px", height = "200px")
    )
  )
}


handwritingServer <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      
      observe({
        session$sendCustomMessage("initialize", message = id)
      })
    
  observeEvent(input$clear_canvas, {
    session$sendCustomMessage("clearCanvas", message = id)
  })
  
  observeEvent(input$send, {
    session$sendCustomMessage("sendCanvas", message = id)
  })
  
  observeEvent(input$undo, {
    print("Undo button clicked")  # Diagnostic output
    session$sendCustomMessage("undoCanvas", message = id)
  })
  
  observeEvent(input$redo, {
    session$sendCustomMessage("redoCanvas", message = id)
  })
  
  observeEvent(input$recognized_text, {
    if (!is.null(input$recognized_text)) {
      updateTextAreaInput(session, "manual_text", value = input$recognized_text)
    }
  })
  
  
  observe({
    session$sendCustomMessage("initCanvas", message = NULL)
  })
  
    }
  )
}

app.R

library(shiny)

ui <- fluidPage(
  tags$head(
    tags$script(src = "handwriting.js"),
    tags$script(src = "handwriting.canvas.js"),
    tags$script(src = "handwriting_for_shiny2.js"),
    tags$style(HTML("
       #handwritingCanvas {
         border: 1px solid #000;
         margin-top: 10px;
         margin-bottom: 10px;
       }
     "))
  ),
  titlePanel("Handwriting Recognition"),
  handwritingUI("module1")
)

server <- function(input, output, session) {
  handwritingServer("module1")
}

shinyApp(ui, server)

mod_simple.R

mod_simple_ui <- function(id) {
  ns <- NS(id)
  tagList(
    handwritingUI(ns("foo"))
  )
}

mod_simple_server <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      ns <- session$ns
      handwritingServer(ns("foo"))
    }
  )
}

app2.R

library(shiny)

ui <- fluidPage(
  tags$head(
    tags$script(src = "handwriting.js"),
    tags$script(src = "handwriting.canvas.js"),
    tags$script(src = "handwriting_for_shiny2.js"),
    tags$style(HTML("
       #handwritingCanvas {
         border: 1px solid #000;
         margin-top: 10px;
         margin-bottom: 10px;
       }
     "))
  ),
  titlePanel("Handwriting Recognition"),
  mod_simple_ui("module1")
)

server <- function(input, output, session) {

  mod_simple_server("module1")
}

shinyApp(ui, server)

Debugging the JS code:

I have put console.log statements in the JS code. I see both prints with app.R but only This is initialize function with app2.R. Somehow, the clearCanvas function is not triggered (and so are the other button functions). This seems to be a namespace issue. I’d appreciate any help.