Browsing all posts tagged javascript

Wordle Helper 2

Mar 23, 2022

My previous Wordle helper has now been supplanted by a newer variant, which adds a number of nice new features. Here's a screenshot of the new UI:

Wordle Helper 2

The top five rows represent the slots for each character of the five-letter word. Each row consists of four controls:

  • The left-most column displays the possible remaining choices for that position.
  • The column with a red background is where you specify letters that are in the word, but not in the given position.
  • The column with a green background is where you specify letters that are in the word and are in the given position.
  • The final column shows the subset of possibilities using only the letters known to be in the word.

As long as the body of the page has focus, you may simply type letters to remove them from play. Holding shift while typing a letter will add that letter to the pool of known letters. Holding the control key will remove the letter from the pool (if you make a mistake). Be careful with this, however; some browser shortcuts cannot reliably be trapped (ctrl + w being one of them).

As an alternative to typing, you can click the on-screen keyboard to remove letters, and Shift + click letters to add them. Here's a second screenshot showing the tool while in use:

Wordle Helper 2 (in use)

Wordle Helper

Feb 23, 2022
Note that this has been replaced by a newer version.

I've been enjoying Wordle, despite the transition to The New York Times (I expect the game to disappear behind the paywall sometime in the near future). Some of the variants of Wordle have also been enjoyable, my favorite among them being Quordle.

One strategy I've used as I've played over the past few weeks is to use a text-editor to keep track of the letters I know are valid, along with their positions. This aids me in figuring out potential words to guess, and others to rule out. Being the programmer that I am, I turned this manual process into a tiny, self-contained web application:

Wordle Helper Screenshot

You enter the characters you know are present in the word in the top box. As you learn about the positions of each character, you also fill in that information. In the example shown above, the word I'm trying to guess is "power." I know the o is in the second position, and I know the w is not in the first position. The resulting choices set at the bottom of each column helps me figure out what it might be.

It was fun to put together this tiny little script.

We use AG-Grid at work for several of our projects. Earlier this week, I ran into an interesting issue in some code being used to load data into the grid. The call was very simple:

agGrid.simpleHttpRequest({url: theURLToLoad })
    .then(function(data) {
        gridOptions.api.setRowData(data);
    });

This asynchronous call was failing and no error was being thrown (as we typically do elsewhere in our code). In looking around, I couldn't determine where the simpleHttpRequest call was defined. The AG-Grid documentation, which is generally pretty good, had no mention of it, save for its use in a few examples. After half an hour of digging, I decided to actually poke around in the AG-Grid source code. There I found the function's definition:

function simpleHttpRequest(params) {
    return new _utils__WEBPACK_IMPORTED_MODULE_0__["Promise"](function (resolve) {
        var httpRequest = new XMLHttpRequest();
        httpRequest.open('GET', params.url);
        httpRequest.send();
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState === 4 && httpRequest.status === 200) {
                resolve(JSON.parse(httpRequest.responseText));
            }
        };
    });
}

All this function is an incredibly light-weight wrapper around XMLHttpRequest. It provides absolutely no support for error handling, and is missing all the other hooks one would need to take full control over the request and its response. It frustrates me when packages do stuff like this. If you're going to show how to fetch remote data for your package, use the vanilla JavaScript features that are industry standard, not some custom wrapper.

AG Grid is the best JavaScript plugin I've ever worked with (I've been meaning to write about it, and I hope to soon). Oddly, one of the few features it doesn't support out of the box is clipboard support for cutting data with Ctrl + X. Copy and paste are provided, but cut support is not. Here's how I added support for this operation (we use the Enterprise variant at work, so this code is geared towards that flavor).

let gridOptions = {
    // ... other grid options ...
    'onCellKeyDown': function(e) {
        if(e.event.key == "x" && (e.event.ctrlKey || e.event.metaKey)) {
            e.api.copySelectedRangeToClipboard();
            e.api.getCellRanges().forEach(range => {
                let colIds = range.columns.map(col => col.colId);
                let startRowIndex = Math.min(
                    range.startRow.rowIndex,
                    range.endRow.rowIndex
                );
                let endRowIndex = Math.max(
                    range.startRow.rowIndex,
                    range.endRow.rowIndex
                );
                clearCells(startRowIndex, endRowIndex, colIds, e.api);
            });
        }
    },
};

let div = document.querySelector("#my-grid");
g_MyGrid = new agGrid.Grid(div, gridOptions);

The clearCells function looks like the following, and handles actually resetting the value of the cell to some default value (I set mine to 0, since I'm working with numerical data):

function clearCells(start, end, columns, gridApi) {
    let itemsToUpdate = [];
    for(let i=start; i<=end; i++) {
        let data = gridApi.rowModel.rowsToDisplay[i].data;
        columns.forEach(column => {
            data[column] = "0";
        });
        itemsToUpdate.push(data);
    }

    gridApi.applyTransaction({update: itemsToUpdate});
}

I've been doing web development in some form or fashion since 1999 (as an aside, the Wayback Machine even has a snapshot of one of my old websites; what a world)! I probably started picking up JavaScript way back in the early 2000s, as my web developing knowledge improved. Since web browsers are generally really good at supporting the old way of doing things, my knowledge of JavaScript has been pretty stagnant for a long time.

Not too long ago, I stumbled upon The Modern JavaScript Tutorial, a terrific resource for learning how to do things the modern way. I'm working my way through reading it, even taking the time to go back over the basics. I've already learned a lot; some of what I've been doing has apparently been deprecated for a while now, which was interesting to learn.

I've also learned about features I hadn't seen before (the nullish coalescing operator being one of those). I recommend it if, like me, you're still living in the dark ages.

It seems like every web browser these days is spending an enormous amount of time and development effort on JavaScript performance. Whether it's the new TraceMonkey engine in Firefox 3.5, the V8 engine in Google Chrome, or the upcoming SquirrelFish engine in WebKit browsers, everyone claims (to some degree) superiority in this arms race. All of this raises two questions in my mind.

1. How important is JavaScript performance? Are JavaScript applications really that slow? I'll admit that the new Firefox 3.5 browser feels snappier on sites like GMail and Netflix, but said sites never felt that slow before. Why are developers spending so much time optimizing something that not everyone uses? Admittedly, JavaScript usage is going up (especially with the Web 2.0 craze), but how much latency does JavaScript computing really account for in today's world? I'm much more concerned about data transfer; that's the bottleneck I see. Broadband speeds here in the United States are ridiculously slow, compared to other parts of the world. Shouldn't we all focus on ways to improve that? Yes, I know software developers have little control over that kind of infrastructure, but perhaps there are better protocols out there to get data to the end user in a more efficient manner.

2. Won't improved JavaScript performance lead to poorer JavaScript programming? As computers have gotten faster over the past two decades, and as memory sizes have increased, applications have become more bloated and (arguably) slower than before. I'm convinced that if programmers had retained the "every byte matters" mentality from the 1970s, 80s, and early 90s, applications would be leaner and meaner than they are today (especially in the realm of operating systems). Can't the same thing be said for JavaScript programming? As JavaScript engines get faster, serious performance considerations during an application's design phase might become less and less frequent. I'm of the opinion that high performance hardware can lead to sloppy programming. "Well, the application is good enough" is what the pointy-haired bosses of the world would say. Shouldn't the application be the best it can be? Can't one argue that "good enough" isn't necessarily good enough?

I'll be interested to see where this arms race takes us. What do you think?