How I can change the format of the numbers on jquery count-to? [duplicate]

Hi and thanks for reading me. I am using a Jquery function to count numbers but I would like to add commas to the numbers (in addition to a prefix), but I can’t find a way to do it so far. I tried using formatter: function (value, options) {return value.toFixed(options.decimals).replace(/B(?=(d{3})+(?!d))/g,","); but it doesn’t work yet. 🙁

My code is the following:

Main.js file:

$('.count-item').each(function(i) {
            $(this).appear(function() {
                var number = $(this).find('.count-to').data('countto');
                $(this).find('.count-to').countTo({from: 0, to: number, speed: 1500, refreshInterval: 10, formatter: function (value, options) {
           return value.toFixed(options.decimals).replace(/B(?=(d{3})+(?!d))/g, ",");
        }
                    
                });
            });
        });

plugins.js file:

(function($) {
    $.fn.countTo = function(options) {
        // merge the default plugin settings with the custom options
        options = $.extend({}, $.fn.countTo.defaults, options || {});

        // how many times to update the value, and how much to increment the value on each update
        var loops = Math.ceil(options.speed / options.refreshInterval),
            increment = (options.to - options.from) / loops;

        return $(this).each(function() {
            var _this = this,
                loopCount = 0,
                value = options.from,
                interval = setInterval(updateTimer, options.refreshInterval);

            function updateTimer() {
                value += increment;
                loopCount++;
                $(_this).html(value.toFixed(options.decimals));

                if (typeof(options.onUpdate) == 'function') {
                    options.onUpdate.call(_this, value);
                }

                if (loopCount >= loops) {
                    clearInterval(interval);
                    value = options.to;

                    if (typeof(options.onComplete) == 'function') {
                        options.onComplete.call(_this, value);
                    }
                }
            }
        });
    };

    $.fn.countTo.defaults = {
        from: 0,  // the number the element should start at
        to: 100,  // the number the element should end at
        speed: 500,  // how long it should take to count between the target numbers
        refreshInterval: 100,  // how often the element should be updated
        decimals: 0,  // the number of decimal places to show
        onUpdate: null,  // callback method for every time the element is updated,
        onComplete: null,  // callback method for when the element finishes updating
        formatter: function (value, options) {
           return value.toFixed(options.decimals).replace(/B(?=(d{3})+(?!d))/g, ",");
        }
    };
})(jQuery);

Index.html file:

<div class="count-item mb-sm-40">
                  <div class="count-icon"><span class="icon-piechart"></span></div>
                  <h3 class="count-to font-alt" data-countto=100></h3>
                  <h5 class="count-title font-serif">Siniestralidad (%)</h5>
                </div>

Anyone know what I could do about it or if there is a solution? I can’t find anything until now

Thanks for the help

I am new to node js and I have some problem with post using postman

I am new to node.js and learning it for quite few days and now I’m stuck with this app.post which is not working for me. If possible please let me know how to do app.update so it might be a big help in my learning process.
Kindly waiting for reply.

const mysql = require('mysql');
const express = require('express');
var app = express();
const bodyparser = require('body-parser');
app.use(bodyparser.urlencoded({extended: false}));
app.use(bodyparser.json());
app.listen(8000);
var mysqlconnection = mysql.createConnection(
    {
        host: 'localhost',
        user: 'Naveen',
        password: '',
        database: 'employeedb',
        multipleStatements: true
    }
);

mysqlconnection.connect((err)=>{
    if(!err)
    console.log("DB connection successfull");
    else
    console.log('DB connection failed n Error : '+ JSON.stringify(err, undefined, 2) );
});
app.post('/employee' ,function (req, res, next) {
    Name = req.query.Name, 
    Empcode = req.query.Empcode,
    Salary = req.query.Salary 
    let sql = "INSERT INTO employee (Name, Empcode, Salary) VALUES (? , ?, ?)";  
    mysqlconnection.query('sql, (Name, Empcode, Salary) ', (err, rows, fields) => {
        if (!err)
            res.send("Insert succeed");
        else
            console.log(err);
        });
    });    
    ```
and then I get these error messages:

**PS C:xampphtdocsfirst app> node index.js DB connection successfull Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql, (Name, Empcode, Salary)' at line 1
   (C:xampphtdocsfirst appnode_modulesexpresslibrouterindex.js:275:10) {   code: 'ER_PARSE_ERROR',   errno: 1064,   sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql, (Name, Empcode, Salary)' at line 1",   sqlState: '42000',   index: 0,   sql: 'sql, (Name, Empcode, Salary) ' }**

Multiple reference queries with export functions to assign specific badges to Wix members

I’ve got series of automations made in the backend of Wix which I’m trying to cross-reference within an onClick function which will automatically assign member badges to members based on specific criteria from a dataset pulled from Google Sheets API and stored in Wix in the collection “Members”.

This is an export function which is triggered by a button on a custom Admin Dashboard. Once a member joins the site, their email address from PrivateMembersData is cross-referenced with the “Members” to find their “type” (name of the badge to be assigned) and push their memberId to an array. It then runs the assignMembers backend function in Wix which is expecting (badgeId, memberIds). Most members have multiple badges to be assigned, and they are all entered as individual rows in the “Members” collection.

The problem I am having is that it seems to be only assigning certain badges and not others, and specifically getting console errors which are telling me memeberIds is in an invalid format. I’m new to js and navigating Wix’s backend and wondering if I’m missing an obvious step. Please help! Thanks in advance.

import wixData from 'wix-data'
import { assignBadge, removeBadge } from 'backend/badges.jsw';
import { assignMembersBackendFunction } from 'backend/badges';
let Badge_A = "b2e41432-xxx-585a28c34da5"
let Badge_B = "8b77b069-xxx-1b9fc066d370"
let Badge_C = "9759af91-xxx-cdb2a9b32dc0"
let Badge_D = "2e598b2d-xxx-de48ff644c9f"
let Badge_E = "f272734e-xxx-e33443395ae8"

export function assignAllBadgeButton_click() {
    let badge = "";
    let BA = [""]
    let BB = [""]
    let BC = [""]
    let BD = [""]
     wixData.query("Members")
        .find()
        .then((results) => {
            results.items.forEach(item => {
                let type = item.type
                wixData.query("Members/PrivateMembersData")
                    .eq("loginEmail", item.email)
                    .find()
                    .then((result) => {
                        let member = result.items[0]
                        console.log(member)
                        // clearBadges(member)

                        if (type == "Badge A Name") {
                            BA.push(member._id)
                            doSomething(BA, Badge_A)

                        }
                        else if (type == "Badge B Name") {

                            BB.push(member._id)
                            doSomething(BB, Badge_B)

                        }
                        else if (type == "Badge C Name") {
                            BC.push(member._id)
                            doSomething(BC, Badge_C)
                        }
                        else if (type == "Badge D Name") {
                            BD.push(member._id)
                            doSomething(BC, Badge_D)

                        } else {
                            console.log("no match")
                        }

                        doSomething(BA, Badge_A);
                        doSomething(BB, Badge_B);
                        doSomething(BC, Badge_C);
                        doSomething(BD, Badge_D)
                        
                    })
            })

        })

}

export function doSomething(userIDs, badge) {
    let results = userIDs
    for (let i = 0; i < userIDs.length; i++) {

        assignMembersBackendFunction(badge, [results[i]])
            .then((assignedMembers) => {
                console.log(assignedMembers)

                return assignedMembers;
            })

    }

}

export function clearBadges(member) {

    removeBadge(Badge_A, member)
        .then(() => {
            removeBadge(Badge_B, member)
                .then(() => {
                    removeBadge(Badge_C, member)
                        .then(() => {
                            removeBadge(Badge_D, member)
                                .then(() => {
                                   console.log("deleted")
                                        })
                                })
                        })
                })
        })
}

/// IN WIX BACKEND MODULE ///:

import { badges } from 'wix-users-backend';

export function assignBadge(badgeID, userIDs) {
 return badges.assignMembers(badgeID, userIDs);
}

//remove a badge from a list of users
export function removeBadge(badgeID, userIDs) {
 return badges.removeMembers(badgeID, userIDs);
}

export function assignMembersBackendFunction(badgeId, memberIds) {
  return badges.assignMembers(badgeId, memberIds);

Using json.prase to seprating each column javascript

on javascript im coding a scraper for my and for my search is in json and i wanna seprate each column that have value and data but i tried so many methods
it turns out like this

    searchMangaFromElement(element) {
        var obj = JSON.parse(element.text())
        var name = obj.suggestions.map(user => user.value);
        var url = obj.suggestions.map(user => user.data);
        var thumbnail = `${this.baseUrl}/uploads/manga/${url}/cover/cover_250x350.jpg`
        var rank = '0';
        return super.manga(name,url,thumbnail,rank);
    }
{
  "mangas": [
    {
      "name": [
        "The Boxer",
        "I'm the Grim Reaper",
        "The Girl Downstairs",
        "The Beginning After the End",
        "The God of High School",
        "The Gamer",
        "The Red King",
        "Boyfriend of the Dead",
        "The Tutorial is Too Hard",
        "Mook-Hyang The Origin",
        "I'm a Martial Art Villainess, but I'm the Strongest!",
        "The Tutorial Tower of the Advanced Player",
        "My Level's the Best",
        "The Throne",
        "The Legendary Mechanic",
        "The Newlywed Life of a Witch and a Dragon",
        "The Player that can't Level Up",
        "Return of the Frozen Player",
        "Capture the Golem and Escape Poverty",
        "The Thorn That Pierces Me",
        "The First Night With the Duke",
        "A Way to Protect the Lovable You",
        "Return of the Female Knight",
        "The Strongest Florist",
        "Return of the Mount Hua Sect",
        "The Villainess is a Marionette",
        "The Princess Imprints a Traitor",
        "Overnight With The Emperor",
        "Kill the Villainess",
        "The Constellation That Returned From Hell",
        "The Pampered Regent of the Richest Woman",
        "The Four of Them",
        "The Kiss Bet",
        "The Lord’s Coins Aren’t Decreasing?!",
        "The Sword Of Dawn",
        "The Hip Guy",
        "Rise From The Rubble",
        "The Supreme Dantian",
        "The Remarried Empress",
        "Reformation of the Deadbeat Noble",
        "The Build Up",
        "Taming The Lady",
        "I Became the Tyrant’s Secretary",
        "Men of the Harem",
        "How The Knight Lives As A Lady",
        "So I Married the Anti-Fan",
        "The Game That I Came From",
        "The Heavenly Demon Can’t Live a Normal Life",
        "The Dexter Attack",
        "Nevertheless",
        "Reincarnation of the Suicidal Battle God",
        "The Makeup Remover",
        "Nevertheless, I love you.",
        "My Path to Killing Gods in Another World",
        "The Blade of Evolution Walking Alone In The Dungeon",
        "The Strongest Warrior Goes to School",
        "The King Of Bugs",
        "The Dark Magician Transmigrates After 66666 Years",
        "Return of the 8th class Magician",
        "The Max Level Hero has Returned!",
        "The Supreme Dantian",
        "The Book of Lagier",
        "The Ancient Sovereign of Eternity",
        "The Heavenly Demon Destroys the Lich King’s Murim",
        "Throne of the Dragon King",
        "There Must Be Happy Endings",
        "The Return of the Crazy Demon",
        "I Reincarnated As The Crazed Heir",
        "Tricked into Becoming the Heroine's Stepmother",
        "I Become a Doting Father",
        "Long Way of the Warrior",
        "Record of the Mightiest Lord",
        "The Earth Savior Selection",
        "Leveling With The Gods",
        "The Double Agent",
        "I’m the Only One Loved by the Constellations!",
        "The Blood of the Butterfly",
        "Don’t Get Me Wrong, I’m The Real Victim!",
        "My Younger Brother's Friend",
        "The Witch and The Bull",
        "The Male Lead's Girl Friend",
        "This is the Law",
        "The Fantasie of a Stepmother",
        "The Lone Necromancer",
        "The Challenger",
        "The Great Mage that Returned after 4000 Years",
        "The Tomb of Famed Swords",
        "Protect the Knight",
        "Foreigner on the Periphery",
        "Return of the Legendary Spear Knight",
        "Return of the Legend",
        "The S-Classes That I Raised",
        "The Time of the Terminally ill Extra",
        "Return of the Broken Constellation",
        "I Am the Fated Villain",
        "The Frenzy Of Evolution",
        "The Strongest Player"
      ],
      "url": [
        "th3-b0xer",
        "7854-im-the-grim-reaper",
        "th3-girl-d0wnstairs",
        "th3-beginning-aft3r-the-end",
        "the-g0d-of-high-sch00l",
        "th3-gam3r",
        "the-red-king",
        "414-boyfriend-of-the-dead",
        "2-the-tutorial-is-too-hard",
        "4742-the-origin",
        "im-a-martial-art-villainess-but-im-the-strongest",
        "85-the-tutorial-tower-of-the-advanced-player",
        "12-my-levels-the-best",
        "74-the-thr0ne",
        "54-the-legendary-mechanic",
        "th3-newlywed-life-of-a-witch-and-a-drag0n",
        "the-player-that-cant-level-up",
        "0-return-of-the-frozen-player",
        "capture-the-golem-and-escape-poverty",
        "44-the-th0rn-that-pierces-me",
        "th3-first-night-with-the-duk3",
        "474-a-way-to-protect-the-lovable-you",
        "44-return-of-the-female-knight",
        "477-the-strongest-fl0rist",
        "return-0f-the-mount-hua-sect",
        "554-the-villainess-is-a-mari0nette",
        "the-princess-imprints-a-traitor",
        "0vernight-with-the-emper0r",
        "85-kill-the-villainess",
        "the-c0nstellation-that-returned-from-hell",
        "the-pampered-regent-of-the-richest-woman",
        "th3-f0ur-0f-them",
        "th3-kiss-b3t",
        "the-lords-coins-arent-decreasing",
        "the-sword-of-dawn",
        "558-the-hip-guy",
        "rise-from-the-rubble",
        "747-the-supreme-dantian",
        "44-th3-remarried-empress",
        "98-reformation-of-the-deadbeat-noble",
        "th3-build-up4",
        "taming-the-lady",
        "i-became-the-tyrants-secretary",
        "men-of-the-harem",
        "how-the-knight-lives-as-a-lady",
        "87-so-i-married-the-antifan",
        "the-game-that-i-came-from",
        "the-heavenly-demon-cant-live-a-normal-life",
        "the-dexter-attack",
        "n3verthel3ss",
        "reincarnation-of-the-suicidal-battle-god",
        "the-makeup-remover",
        "nevertheless-i-love-you",
        "my-path-to-killing-gods-in-another-world",
        "the-blade-of-evolution-walking-alone-in-the-dungeon",
        "the-strongest-warrior-goes-to-school",
        "the-king-of-bugs",
        "the-dark-magician-transmigrates-after-66666-years",
        "return-of-the-8th-class-magician",
        "the-max-level-hero-has-returned",
        "the-supreme-dantian",
        "the-book-of-lagier",
        "the-ancient-sovereign-of-eternity",
        "the-heavenly-demon-destroys-the-lich-kings-murim",
        "throne-of-the-dragon-king",
        "there-must-be-happy-endings",
        "the-return-of-the-crazy-demon",
        "i-reincarnated-as-the-crazed-heir",
        "tricked-into-becoming-the-heroines-stepmother",
        "i-become-a-doting-father",
        "long-way-of-the-warrior",
        "record-of-the-mightiest-lord",
        "the-earth-savior-selection",
        "leveling-with-the-gods",
        "the-double-agent",
        "im-the-only-one-loved-by-the-constellations",
        "the-blood-of-the-butterfly",
        "dont-get-me-wrong-im-the-real-victim",
        "my-younger-brothers-friend",
        "the-witch-and-the-bull",
        "the-male-leads-girl-friend",
        "this-is-the-law",
        "the-fantasie-of-a-stepmother",
        "the-lone-necromancer",
        "the-challenger",
        "the-great-mage-that-returned-after-4000-years",
        "the-tomb-of-famed-swords",
        "protect-the-knight",
        "foreigner-on-the-periphery",
        "return-of-the-legendary-spear-knight",
        "return-of-the-legend",
        "the-sclasses-that-i-raised",
        "the-time-of-the-terminally-ill-extra",
        "return-of-the-broken-constellation",
        "i-am-the-fated-villain",
        "the-frenzy-of-evolution",
        "the-strongest-player"
      ],
      "thumbnail": "https://zahard.xyz/uploads/manga/th3-b0xer,7854-im-the-grim-reaper,th3-girl-d0wnstairs,th3-beginning-aft3r-the-end,the-g0d-of-high-sch00l,th3-gam3r,the-red-king,414-boyfriend-of-the-dead,2-the-tutorial-is-too-hard,4742-the-origin,im-a-martial-art-villainess-but-im-the-strongest,85-the-tutorial-tower-of-the-advanced-player,12-my-levels-the-best,74-the-thr0ne,54-the-legendary-mechanic,th3-newlywed-life-of-a-witch-and-a-drag0n,the-player-that-cant-level-up,0-return-of-the-frozen-player,capture-the-golem-and-escape-poverty,44-the-th0rn-that-pierces-me,th3-first-night-with-the-duk3,474-a-way-to-protect-the-lovable-you,44-return-of-the-female-knight,477-the-strongest-fl0rist,return-0f-the-mount-hua-sect,554-the-villainess-is-a-mari0nette,the-princess-imprints-a-traitor,0vernight-with-the-emper0r,85-kill-the-villainess,the-c0nstellation-that-returned-from-hell,the-pampered-regent-of-the-richest-woman,th3-f0ur-0f-them,th3-kiss-b3t,the-lords-coins-arent-decreasing,the-sword-of-dawn,558-the-hip-guy,rise-from-the-rubble,747-the-supreme-dantian,44-th3-remarried-empress,98-reformation-of-the-deadbeat-noble,th3-build-up4,taming-the-lady,i-became-the-tyrants-secretary,men-of-the-harem,how-the-knight-lives-as-a-lady,87-so-i-married-the-antifan,the-game-that-i-came-from,the-heavenly-demon-cant-live-a-normal-life,the-dexter-attack,n3verthel3ss,reincarnation-of-the-suicidal-battle-god,the-makeup-remover,nevertheless-i-love-you,my-path-to-killing-gods-in-another-world,the-blade-of-evolution-walking-alone-in-the-dungeon,the-strongest-warrior-goes-to-school,the-king-of-bugs,the-dark-magician-transmigrates-after-66666-years,return-of-the-8th-class-magician,the-max-level-hero-has-returned,the-supreme-dantian,the-book-of-lagier,the-ancient-sovereign-of-eternity,the-heavenly-demon-destroys-the-lich-kings-murim,throne-of-the-dragon-king,there-must-be-happy-endings,the-return-of-the-crazy-demon,i-reincarnated-as-the-crazed-heir,tricked-into-becoming-the-heroines-stepmother,i-become-a-doting-father,long-way-of-the-warrior,record-of-the-mightiest-lord,the-earth-savior-selection,leveling-with-the-gods,the-double-agent,im-the-only-one-loved-by-the-constellations,the-blood-of-the-butterfly,dont-get-me-wrong-im-the-real-victim,my-younger-brothers-friend,the-witch-and-the-bull,the-male-leads-girl-friend,this-is-the-law,the-fantasie-of-a-stepmother,the-lone-necromancer,the-challenger,the-great-mage-that-returned-after-4000-years,the-tomb-of-famed-swords,protect-the-knight,foreigner-on-the-periphery,return-of-the-legendary-spear-knight,return-of-the-legend,the-sclasses-that-i-raised,the-time-of-the-terminally-ill-extra,return-of-the-broken-constellation,i-am-the-fated-villain,the-frenzy-of-evolution,the-strongest-player/cover/cover_250x350.jpg",
      "rank": "0"
    }
  ],
  "hasNextPage": 1,
  "nextPage": 1,
  "results": 1
}

I tried it doing it like that same thing but now prints one thing from it

    searchMangaFromElement(element) {
        var obj = JSON.parse(element.text())
        for (var vals in obj. suggestions) {
        var url = obj.suggestions[vals].data;
        var name = obj.suggestions[vals].value;
        var thumbnail = `${this.baseUrl}/uploads/manga/${url}/cover/cover_250x350.jpg`
        var rank = '0';
        return super.manga (name, url, thumbnail,rank);
        }
    }
{
  "mangas": [
    {
      "name": "The Boxer",
      "url": "th3-b0xer",
      "thumbnail": "https://zahard.xyz/uploads/manga/th3-b0xer/cover/cover_250x350.jpg",
      "rank": "0"
    }
  ],
  "hasNextPage": 1,
  "nextPage": 1,
  "results": 1
}

the default was using cheerio to find specific things and it prints like that

{
  "mangas": [
    {
      "name": "10 Years in the Friend Zone",
      "url": "/manga/2053/10-years-in-the-friend-zone",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5faa0b5f66d2cb714b2b2df9.png?1640316529137?",
      "rank": "0"
    },
    {
      "name": "10th - You and I Fell in Love With the Same Person.",
      "url": "/manga/2107/10th-you-and-i-fell-in-love-with-the-same-person",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fab17b842e2937121a252de.jpg?1640316299796?",
      "rank": "0"
    },
    {
      "name": "11 Eyes - Tsumi to Batsu to Aganai no Shoujo",
      "url": "/manga/1517/11-eyes-tsumi-to-batsu-to-aganai-no-shoujo",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f97927ab5ef1960d7b17505.jpg?1640315012618?",
      "rank": "0"
    },
    {
      "name": "25-ji no Ghost Writer",
      "url": "/manga/2153/25-ji-no-ghost-writer",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fab6a8925d77b716a370f7b.jpg?1640316101771?",
      "rank": "0"
    },
    {
      "name": "2ban-me no Alpha",
      "url": "/manga/2343/2ban-me-no-alpha",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fe26d358d9b52437f740e69.jpg?1640316826822?",
      "rank": "0"
    },
    {
      "name": "30-sai, Shojo OL",
      "url": "/manga/852/30-sai-shojo-ol",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f7a5fbb9c50b229a3c2a156.jpg?1640308964416?",
      "rank": "0"
    },
    {
      "name": "5Toubun no Hanayome",
      "url": "/manga/739/5toubun-no-hanayome",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f78e1e428b7864469d947b7.jpg?1640316701098?",
      "rank": "0"
    },
    {
      "name": "666 Satan",
      "url": "/manga/934/666-satan",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f7b9fb2fd59c26384219b17.jpg?1640315727785?",
      "rank": "0"
    },
    {
      "name": "A Deal With the Devil",
      "url": "/manga/2351/a-deal-with-the-devil",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fe45e578264bc2beea65a16.jpg?1640312615522?",
      "rank": "0"
    },
    {
      "name": "A Maid With Special Circumstances and the Young Miss Who Wants to Get Along",
      "url": "/manga/1903/a-maid-with-special-circumstances-and-the-young-miss-who-wants-to-get-along",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fa600806d472b71ce0aebd5.jpg?1640305967164?",
      "rank": "0"
    },
    {
      "name": "A Story About Confessing Before the End of the World",
      "url": "/manga/992/a-story-about-confessing-before-the-end-of-the-world",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f7bdefefd59c2638421bb15.jpg?1640316238461?",
      "rank": "0"
    },
    {
      "name": "A Story About a Grandpa and Grandma Who Returned Back to Their Youth",
      "url": "/manga/1686/a-story-about-a-grandpa-and-grandma-who-returned-back-to-their-youth",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fa0b0ae468a6c1ea40b221c.jpg?1640307533358?",
      "rank": "0"
    },
    {
      "name": "A Tender Heart: The Story of How I Became a Duke's Maid",
      "url": "/manga/2477/a-tender-heart-the-story-of-how-i-became-a-duke-s-maid",
      "thumbnail": "https://cdn.mangaworld.in/mangas/6086262598a5c33b63211285.jpg?1640316531952?",
      "rank": "0"
    },
    {
      "name": "A Trace of You",
      "url": "/manga/2021/a-trace-of-you",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5fa9c8d46af12c711b4702a7.jpg?1640314754722?",
      "rank": "0"
    },
    {
      "name": "Adamasu no Majotachi",
      "url": "/manga/1642/adamasu-no-majotachi",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f9cc2de7b46fd1e2d722356.jpg?1640316533446?",
      "rank": "0"
    },
    {
      "name": "Ageha o Ou Monotachi",
      "url": "/manga/551/ageha-o-ou-monotachi",
      "thumbnail": "https://cdn.mangaworld.in/mangas/5f7663ba191ebd03ee7f23b9.jpg?1640315024255?",
      "rank": "0"
    }
  ],
  "hasNextPage": true,
  "nextPage": 2,
  "results": 16
}

Fetch data from Strava API and return data to table

I’ve tried quite a few things and read a lot of examples of using the data returned by Fetch as an object to put into a table or similar but I can’t seem to get it. The following code authorises the Strava user to use my test App and then gets the Users last 30 activities. Once data is returned as a Promise I can view it in the console, but not use it. I’m a bit of a novice so just need some direction on how to use this data in table.

//my code is below


<script>

    //reAuthorize Click
    function Authorize() {
            document.location.href = "https://www.strava.com/oauth/authorize?client_id=73630&redirect_uri=https://localhost:44370/strava/index&response_type=code&scope=activity:read_all"
    }

    const codeExchangeLink = `https://www.strava.com/api/v3/oauth/token`
    function codeExchange() {


        fetch(codeExchangeLink, {
            method: 'post',
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Content-Type': 'application/json'
            },

            body: JSON.stringify({
                client_id: '@ViewBag.cId',
                client_secret: '@ViewBag.cSec',
                code: '@ViewBag.code',
                //need to do this to get a new refresh token that 'reads all' and issues a new Access Token - refer to comments below
                grant_type: 'authorization_code'
            })
        })
            .then(res => res.json())
            .then(res => getActivities(res))
 
    }

    //  getActivities
    const auth_link = "https://www.strava.com/oauth/token"

    function getActivities(res) {

        var obj;
        const activities_link = `https://www.strava.com/api/v3/athlete/activities?access_token=${res.access_token}`
        fetch(activities_link)
            .then((res) => console.log(res.json()))

    }

</script>


<form asp-action="Index" method="get">
    <input type="text" id="cId" value="@ViewBag.cId" />
    <input type="text" id="cSec" value="@ViewBag.cSec" />
    <input type="text" id="rT" value="@ViewBag.rT" />
    <input type="text" id="code" value="@ViewBag.code" />
    <input type="text" id="test" />
</form>
<input type="button" onclick="Authorize()" value="ReAuthorise" />
<input type="button" onclick="codeExchange()" value="Get Activities" />

enter image description here

How to return value of form to WASM when button clicked

I need to have a function that returns the value of a form to my WASM code when a button is clicked.

I tried

let formText = ''
      //import init, {greet} from "./pkg/hello_wasm.js";
      Element.prototype.remove = function() {
       this.parentElement.removeChild(this);
      }
      function getFormText(){
       formText = document.getElementById('tField').value
      }
      function readDom(){
        document.write('<input type="text" id="tField"><button type="button" id="submit" onClick = "getFormText()">Submit</button>')
        while(formText == ''){
                  
        } 
        let bufText = formText
        document.getElementById('tField').remove
        document.getElementById('submit').remove
        formText = ''
        return bufText
      }
      document.write(readDom())
      /*init()
        .then(() => {
          greet("WebAssembly")
        });*/

but it just froze my browser.
I looked up “wait for button click” and stuff like that on DuckDuckGo but the results I got didn’t do what I needed.

Putting the document.write in the callback won’t work because the function is meant to be called from WASM/return to WASM I just have the WASM commented out so I don’t have to recompile my code just to test changes to a JS function.

How to make a Canvas boundary

I am trying to make a canvas boundary for my mini-game. I have already created the canvas with a character that can move with the arrows. I used a switch statement to do this, the next step is to create a boundary and I am not sure how to go about that? This is how the Javascript Code looks at the moment:

function place(id,x_pos, y_pos)
{
  let element = document.getElementById(id);
  element.style.position = "absolute";
  element.style.left = x_pos + 'px';
  element.style.top = y_pos + 'px';


}

setInterval(update,1);

function update()
{
  document.addEventListener('keydown', keyPress);
}

function keyPress(e)
{
  let x = e.keyCode;

  let character = document.getElementById("character").getBoundingClientRect();
  let canvasWidth = document.getElementById("canvas").getBoundingClientRect();
  let left = parseInt(character.left,10);
  let top = parseInt(character.top,10)

  switch (x) {

      //left
    case 37:
        place('character', left-15, top);
      break;
      //right
    case 39:
        place('character', left+15, top);
      break;
      //up
    case 38:
        place('character', left, top-15);
      break;
      //down
    case 40:
        place('character', left, top+15);
      break;
  }
  console.log(x)
  return x
}
update()

Checkbox onchange function is always undefined in React component class

My onchange function on my checkbox is always undefined. I made a sandbox to simplify my issue. I’ve tried changing it back and forth between an arrow and a regular function, and leaving the binding as its default state vs tying it to its binding in the constructor.

import "./styles.css";
import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);

    this.renderCheckboxes = this.renderCheckboxes.bind(this);
    this.checkboxChange = this.checkboxChange.bind(this);
  }

  checkboxChange = (event) => {
    console.log("CHANGED");
  }

  renderCheckboxes(checkboxes) {
    return checkboxes.map(function (obj, idx) {
      return (
        <div>
          <label>{obj.name}</label>
          <input type="checkbox" onChange={this.checkboxChange} />
        </div>
      );
    });
  }

  render() {
    const cbList = [
      { name: "A", mood: "Happy" },
      { name: "B", mood: "Sad" },
      { name: "C", mood: "Mad" }
    ];

    return <>{this.renderCheckboxes(cbList)}</>;
  }
}

export default App;

My Sandbox

Wrapping the arguments or result of an anonymous function

I want to reassign an anonymous function to add to what it does. I’m basically looking the below functionality.

let f1 = (x: number) => x + 100;
// f1 = (x: number) => f1(x) + 20; // becomes recursive -> stack overflow, not what I want
f1(3) // 123

The two options I see are either 1. wrapping the argument or 2. somehow wrapping the result. The first option seems easier but I’m not sure how to accomplish it (or if what I’m asking for is impossible).

Second input keep showing the same input value eventhough the value in the first input is inserted differently everytime

This is a follow-up question from the question that I’ve asked before:

Autofill the 2nd input after the 1st input value is filled based on the if/else range condition. Below is the answer is given by @Muge which I follow to solve it.

https://stackoverflow.com/a/70433191/16136444

But I encountered a problem, the second input keep showing the same input value even though the value in the first input is inserted differently every time. It keeps giving me the value of “G1” no matter what number value that I put on the first input.

2nd input always show G1

What could be wrong with my code?

vue template

<v-col cols="12" sm="6" md="6">
    <label style="font-size: 1.5rem;">Estimated Contract Value (RM)</label>
    <v-text-field
        v-model="editedItem.EstimatedContractValue"
        outlined
        @blur="updateWorksGrade"
    ></v-text-field> 
</v-col>
<v-col cols="12" sm="6" md="6">
    <label style="font-size: 1.5rem;">Works Grade</label>
    <v-text-field
        v-model="editedItem.WorksGrade"
        outlined
        readonly
        :items="worksgrade"
    ></v-text-field>
</v-col>

vue script

data: () => ({
    editedItem: {
        EstimatedContractValue: "",
        WorksGrade: "",
    },
    worksgrade: [],
}),

methods: {
    updateWorksGrade() {
        this.worksgrade = [];
        let x = [];
        if ( x < 200000) {
            this.editedItem.WorksGrade = "G1";
        } else if ( x > 200000 && x <= 500000) {
            this.editedItem.WorksGrade = "G2";
        } else if ( x > 500000 && x <= 1000000) {
            this.editedItem.WorksGrade = "G3";
        } else if ( x > 1000000 && x <= 3000000) {
            this.editedItem.WorksGrade = "G4";
        } else {
            alert("oi lebih dah ni!")
        }
    },
},

How do I test that a click event occurred using Jasmine?

I am trying to test a click event in app.spec.js using Jasmine with the code below and am getting an error that says the following. Any suggestions? I’m not sure how to refer to the element.

I have tried different methods to refer to the DOM. Do I need to create a mock of document? I am pretty new to creating these type of tests.

Error

When the +1 Player 1 button is pressed > should call incrementPlayerOneScore
TypeError: Cannot read properties of null (reading 'click')
TypeError: Cannot read properties of null (reading 'click')
    at UserContext.<anonymous> (file:///C:/Users/charl/Documents/WebDev/PingPongScorekeeper/spec/app.spec.js:9:56)
    at <Jasmine>

app.html

<!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">
    <link rel="stylesheet" href="app.css">
    <title>Ping Pong Scorekeeper</title>
</head>

<body>
    <h1>Ping Pong Scorekeeper</h1>
    <div>
        <span id="playerOneScore">0</span> to <span id="playerTwoScore">0</span>
    </div>
    <div>
        <p>Use the buttons below to keep score.</p>
    </div>
    <div>
        <label for="winningPointsSelect">Playing To:</label>

        <select name="winningPoints" id="winningPointsSelect">
            <option value="">--Please choose an option--</option>
            <option value="5">5</option>
            <option value="6">6</option>
            <option value="7">7</option>
            <option value="8">8</option>
            <option value="9">9</option>
            <option value="10">10</option>
        </select>
    </div>
    <div>
        <button id="playerOnePointButton">+1 to Player 1</button>
        <button id="playerTwoPointButton">+1 to Player 2</button>
        <button id="resetButton">Reset</button>
    </div>
    <script type="text/javascript" src="src/pingPongGame.js"></script>
    <script type="text/javascript" src="src/app.js"></script>
</body>

</html>

specRunner.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Jasmine Spec Runner v3.10.1</title>

    <link rel="shortcut icon" type="image/png" href="lib/jasmine-3.10.1/jasmine_favicon.png">
    <link rel="stylesheet" href="lib/jasmine-3.10.1/jasmine.css">

    <!-- include source files here... -->
    <script src="src/app.js"></script>
    <script src="src/pingPongGame.js"></script>

    <script src="lib/jasmine-3.10.1/jasmine.js"></script>
    <script src="lib/jasmine-3.10.1/jasmine-html.js"></script>
    <script src="lib/jasmine-3.10.1/boot0.js"></script>
    <!-- optional: include a file here that configures the Jasmine env -->
    <script src="lib/jasmine-3.10.1/boot1.js"></script>



    <!-- include spec files here... -->
    <script src="spec/app.spec.js"></script>
    <script src="spec/pingPongGame.spec.js"></script>
</head>

<body>
</body>

</html>

app.js

const newPingPongGame = new PingPongGame(10);
const resetButton = document.querySelector('#resetButton');

resetButton.addEventListener('click', function () {
    newPingPongGame.isGameWon();
});

pingPongGame.js

class PingPongGame {
    constructor(newWinningPoints) {
        this._playerOneScore = 0;
        this._playerTwoScore = 0;
        this._isGameWon = false;
        this._winningPoints = newWinningPoints;
    }

    get playerOneScore() {
        return this._playerOneScore;
    }

    set playerOneScore(newPlayerOneScore) {
        this._playerOneScore = newPlayerOneScore;
    }

    get playerTwoScore() {
        return this._playerTwoScore;
    }

    set playerTwoScore(newPlayerTwoScore) {
        this._playerTwoScore = newPlayerTwoScore;
    }

    get winningPoints() {
        return this._winningPoints;
    }

    set winningPoints(newWinningPoints) {
        this._winningPoints = newWinningPoints;
    }

    get isGameWon() {
        return this._isGameWon;
    }

    set isGameWon(newIsGameWon) {
        this._isGameWon = newIsGameWon;
    }

    incrementPlayerOneScore() {
        this._playerOneScore++;
    }

    incrementPlayerTwoScore() {
        this._playerTwoScore++;
    }

    resetGame() {
        this._playerOneScore = 0;
        this._playerTwoScore = 0;
        this._winningPoints = 10;
        this._isGameWon = false;
    }

    isGameWon() {
        if (this._playerOneScore == this._winningPoints || this._playerTwoScore == this._winningPoints) {
            this._isGameWon = true;
        } else {
            this._isGameWon = false;
        }
        return this._isGameWon;
    }
}

app.spec.js

describe("When the +1 Player 1 button is pressed", function () {
    it("should trigger a click event", function () {
        document.querySelector("#playerOnePointButton").click();
        expect("click").toHaveBeenTriggeredOn("#playerOnePointButton");
    });
    it("should call incrementPlayerOneScore", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerOneScore = 1;
        document.querySelector("#playerOnePointButton").click();
        let result = newPingPongGame._playerOneScore;
        expect(result).toBe(2);
    });
});

pingPongGame.spec.js

describe("When the pingPongGame constructor is called", function () {
    it("should create a ping pong game with given arguments.", function () {
        let newPingPongGame = new PingPongGame(10);
        expect(newPingPongGame._winningPoints).toBe(10);
    });
    it("should set the value of playerOneScore to zero.", function () {
        let newPingPongGame = new PingPongGame(10);
        expect(newPingPongGame._playerOneScore).toBe(0);
    });
    it("should set the value of playerTwoScore to zero.", function () {
        let newPingPongGame = new PingPongGame(10);
        expect(newPingPongGame._playerTwoScore).toBe(0);
    });
});

describe("When the getter method for playerOneScore is called", function () {
    it("should return the value of playerOneScore.", function () {
        let newPingPongGame = new PingPongGame(10);
        let testValue = newPingPongGame._playerOneScore;
        expect(testValue).toBe(0);
    });
})

describe("When the setter method for playerOneScore is called", function () {
    it("should set the value of playerOneScore.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerOneScore = 1;
        expect(newPingPongGame._playerOneScore).toBe(1);
    });
});

describe("When the getter method for playerTwoScore is called", function () {
    it("should return the value of playerTwoScore.", function () {
        let newPingPongGame = new PingPongGame(10);
        let testValue = newPingPongGame._playerTwoScore;
        expect(testValue).toBe(0);
    });
})

describe("When the setter method for playerTwoScore is called", function () {
    it("should set the value of playerTwoScore.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerTwoScore = 1;
        expect(newPingPongGame._playerTwoScore).toBe(1);
    });
});

describe("When the getter method for winningPoints is called", function () {
    it("should return the value of winningPoints.", function () {
        let newPingPongGame = new PingPongGame(11);
        let testValue = newPingPongGame._winningPoints;
        expect(testValue).toBe(11);
    });
})

describe("When the setter method for winningPoints is called", function () {
    it("should set the value of winningPoints.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._winningPoints = 5;
        expect(newPingPongGame._winningPoints).toBe(5);
    });
});

describe("When incrementPlayerOneScore is called", function () {
    it("should increment playerOneScore by one.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame.incrementPlayerOneScore();
        expect(newPingPongGame.playerOneScore).toBe(1);
    });
});

describe("When incrementPlayerTwoScore is called", function () {
    it("should increment playerTwoScore by one.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame.incrementPlayerTwoScore();
        expect(newPingPongGame.playerTwoScore).toBe(1);
    });
});

describe("When resetGame is called", function () {
    it("should set the value of playerOneScore to zero.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame.incrementPlayerOneScore();
        newPingPongGame.resetGame();
        expect(newPingPongGame.playerOneScore).toBe(0);
    });
    it("should set the value of playerTwoScore to zero.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame.incrementPlayerTwoScore();
        newPingPongGame.resetGame();
        expect(newPingPongGame.playerTwoScore).toBe(0);
    });
    it("should create set winning points to ten.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._winningPoints = 12;
        newPingPongGame.resetGame();
        expect(newPingPongGame._winningPoints).toBe(10);
    });
    it("should set isGameWon to false", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._isGameWon = true;
        newPingPongGame.resetGame();
        expect(newPingPongGame._isGameWon).toBe(false);
    });
});

describe("When isGameWon is called", function () {
    it("should return true if the game is won by player one.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerOneScore = 10;
        let isGameWon = newPingPongGame.isGameWon();
        expect(isGameWon).toBe(true);
    });
    it("should return true if the game is won by player two.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerTwoScore = 10;
        let isGameWon = newPingPongGame.isGameWon();
        expect(isGameWon).toBe(true);
    });
    it("should return false if the game is not won by player one.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerOneScore = 8;
        let isGameWon = newPingPongGame.isGameWon();
        expect(isGameWon).toBe(false);
    });
    it("should return false if the game is not won by player two.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerTwoScore = 8;
        let isGameWon = newPingPongGame.isGameWon();
        expect(isGameWon).toBe(false);
    });
    it("should set the isGameWon value to true if the game is won.", function () {
        let newPingPongGame = new PingPongGame(10);
        newPingPongGame._playerOneScore = 10;
        newPingPongGame.isGameWon();
        let isGameWon = newPingPongGame._isGameWon;
        expect(isGameWon).toBe(true);
    });
});

TypeError: (intermediate value)(intermediate value)(intermediate value) is not iterable

I am trying to use the same table of data on one page it has a filter available and on the main page it doesn’t require the filter but once I switch to the Convert table that has the state passing filtered values COMMENTED OUT I see this error in the title

TypeError: (intermediate value)(intermediate value)(intermediate value) is not iterable

The error seems to only happen once I pass the destructured startDate, endDate through in the ConvertHistoryTable

 const [startDate, endDate] = filterValues?.dateRange
//ConvertHistoryTable
import React from 'react'

import { useNavigate } from 'react-router-dom'
import { format } from 'date-fns'

import TableCell from '@mui/material/TableCell'
import TableRow from '@mui/material/TableRow'
import IconButton from '@mui/material/IconButton'
import PreviewIcon from '@mui/icons-material/Preview'
//  components
import QueryHolder from 'components/ContentWrapper/QueryHolder'
import StaticTable from 'components/Table/StaticTable'
import NumericCell from 'components/Table/cell/NumericCell'
import { TransactionTypeCell } from 'components/Table/cell/TypeCells'
import CurrencyAmountCell from 'components/Table/cell/CurrencyAmountCell'
import ChartContainer from 'components/ChartContainer/ChartContainer'
import ChipsStatus from 'components/Chips/ChipsStatus'
//  hooks
import { useGetExchangedRecord } from 'hooks/exchange'
import { ExchangeOverview } from '../types/Transaction'
import { FilterValues } from '../TransactionsOverview'

type Props = {
  filterValues?: FilterValues
  maxHeight?: number
  small?: boolean
}

export default function ConvertHistoryTable({ filterValues, maxHeight, small }: Props) {
  const [startDate, endDate] = filterValues?.dateRange

  const queryRes = useGetExchangedRecord(
    filterValues?.status,
    filterValues?.creditCurrencyCode,
    filterValues?.debitCurrencyCode,
    startDate ? format(startDate, 'yyyy-MM-dd') : undefined,
    endDate ? format(endDate, 'yyyy-MM-dd') : undefined
  )

  const records: ExchangeOverview[] = queryRes.isSuccess ? queryRes.data.data : []

  return (
    <ChartContainer>
      <QueryHolder queryRes={queryRes}>
        <StaticTable
          small={small}
          maxHeight={maxHeight}
          fieldRows={['Number', 'Type', 'Exchange rate', 'Debit', 'Credit', 'Status', 'Details']}
          valueRows={records.map((item: ExchangeOverview) => (
            <TableItem item={item} key={item.uuid} />
          ))}
        />
      </QueryHolder>
    </ChartContainer>
  )
}

const TableItem = ({ item }: any) => {
  const navigate = useNavigate()

  function handleToDetail(uuid: string) {
    return navigate(`/convert/details/${uuid}`)
  }

  return (
    <TableRow>
      <TableCell>{item.refNum}</TableCell>
      <TransactionTypeCell type={item.type} />
      <NumericCell value={item.exchangeRate} />
      <CurrencyAmountCell currencyCode={item.creditCurrencyCode} amount={item.creditAmount} />
      <CurrencyAmountCell currencyCode={item.debitCurrencyCode} amount={item.debitAmount} />
      <TableCell>
        <ChipsStatus status={item.status} />
      </TableCell>
      <TableCell>
        <IconButton onClick={() => handleToDetail(item.detailsUuid)}>
          <PreviewIcon />
        </IconButton>
      </TableCell>
    </TableRow>
  )
}

//mainpage
type TabPanelProps = {
  children?: React.ReactNode
  index: number
  value: number
}
export type FilterValues = {
  status: string
  currency: string
  creditCurrencyCode: string
  debitCurrencyCode: string
  dateRange: any
}

function TabPanel({ children, value, index, ...other }: TabPanelProps) {
  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`table-tabpanel-${index}`}
      aria-labelledby={`table-tab-${index}`}
      {...other}
    >
      {value === index && <Box>{children}</Box>}
    </div>
  )
}

function a11yProps(index: number) {
  return {
    id: `table-tab-${index}`,
    'aria-controls': `table-tabpanel-${index}`,
  }
}

export default function Dashboard() {
  const [tabValue, setTabValue] = React.useState(0)

  const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
    setTabValue(newValue)
  }

  const [transferFilterValues, setTransferFilterValues] = React.useState<FilterValues>({
    status: '',
    currency: '',
    creditCurrencyCode: '',
    debitCurrencyCode: '',
    dateRange: [null, null],
  })

  // const [exchangeFilterValues, setExchangeFilterValues] = React.useState<FilterValues>({
  //   status: '',
  //   currency: '',
  //   creditCurrencyCode: '',
  //   debitCurrencyCode: '',
  //   dateRange: [null, null],
  // })

  return (
    <Grid container spacing={4}>
      <Grid item xs={12}>
        <AccountBalances />
      </Grid>
      <Grid item xs={12}>
        <Grid container spacing={2}>
          <Grid item xs={12} md={9}>
            <Tabs
              value={tabValue}
              onChange={handleTabChange}
              aria-label="transaction tabs"
              centered
            >
              <Tab label="Transfer" {...a11yProps(0)} />
              <Tab label="Convert" {...a11yProps(1)} />
            </Tabs>
          </Grid>
          <Grid item xs={9} sx={{ display: { xs: 'none', md: 'flex' } }} />
          <Grid item xs={12} md={9}>
            <TabPanel value={tabValue} index={0}>
              <TransferHistoryTable filterValues={transferFilterValues} maxHeight={500} small />
            </TabPanel>
            <TabPanel value={tabValue} index={1}>
              <ConvertHistoryTable maxHeight={500} small />
            </TabPanel>
          </Grid>
          <Grid item xs={12} md={3}>
            <FakeBox height="400px" />
          </Grid>
        </Grid>
      </Grid>
    </Grid>
  )
}

const FakeBox = ({ height }) => (
  <Card
    sx={{
      minHeight: height,
    }}
  >
    <Typography variant="h3">Notification</Typography>
    coming soon...
  </Card>
)

How to calculate maximum of a dynamic column using arquero (javascript)?

Suppose you have a column name (of table data) in the string variable colname … you can try to do something like

let colname = "something"
data.rollup({
  "max": d => aq.op.max(d[colname])
})

but it won’t work because colname is not defined in that scope.

You might try to escape but that doesn’t work either

let colname = "something"
data.rollup({
  "max": aq.escape(d => aq.op.max(d[colname]))
})

The non-dynamic version does work however.

data.rollup({
  "max": d => aq.op.max(d.something)
})

Is there some way of doing this in arquero? Just a column operation like max, min, mean etc?

How to synchronize a timer between the server and all its clients over the internet (down to the millisecond)

I’m writing a tiny online game where every event is kept track of by the time it occurred. Whenever an event happens the current clock (number of milliseconds since the game started) is polled from, and that value dictates exactly the millisecond that that event happened (this allows to server to recreate the entire game world using only these events and the times they happened)

In order to get the server’s recreation of the world to line up as closely as possible with what the players see, I want both the server and the clients to run on the same EXACT timer, as close as possible, preferably down to the millisecond.

What’s the best way to go about this? Currently my two ideas are:

  1. Have the server send a date (in milliseconds) to each client, and have them take that date and determine how many milliseconds ago the server’s clock was started, and then they can start their own clock that many milliseconds in the past.

However, I don’t believe this is reliable since it relies on the client’s clock having the exact same date as the server, which is completely unlikely.

  1. Have the server keep track of all the clients’ pings (latency) and send a latency-compensated timestamp to tell each client what the current time is.

However, this has the flaw of almost always being at least ~5 milliseconds off, since the latency fluctuates constantly.


And both of these solutions suffer from the fact that computer clocks are NOT accurate, and I will need to constantly re-sync the timers to keep them from drifting too far apart…

All of this leads me to believe that there must be some better way to go about this. Any tips or advices are greatly appreciated.