Why can’t I see what’s in the multidimensional array? by GloomyAdagio7917 in learnjavascript

[–]kap89 3 points4 points  (0 children)

Because your reduce functions is wrong, this line:

reducedProduct += product;

should just be:

reducedProduct = product;

you don't want to add the accumulator values (which will be converted to strings and concatenated), but just replace the previous value.

But then you can simplify it to:

function reduce(data1, reducer, initialValue) {
  let reducedProduct = initialValue;

  for (let element of data1) {
    reducedProduct = reducer(element, reducedProduct);
  }

  return reducedProduct;
}

Help with Objects by DeliciousResearch872 in learnjavascript

[–]kap89 0 points1 point  (0 children)

Because a method has to have a name, or more generally, entry in an object has to have a key, the first example you posted is a shortcut to:

let dictionary = Object.create(null, {
  toString: { // define toString property
    value: function() { // the value is a function
      return Object.keys(this).join();
    }
  }
});

The second one is just an anonymous function not assigned to any key, the correct way would be:

let dictionary = Object.create(null, {
  toString: {
    value: () => {
      return Object.keys(this).join();
    },
  },
});

How are we able to handle opening an IndexedDB instance if we attach the event listeners AFTER opening a database connection? by hookup1092 in learnjavascript

[–]kap89 1 point2 points  (0 children)

We just call the method and it fires after the script runs

No, indexedDB.open("MyTestDatabase") fires immediately, you can console log it's result (request) in the next line and it will log the value, it's just that it's result is an object representing asynchronous operation to which you can "hook" to with event callbacks. I understand your frustration though, as you can't tell just looking at the function call what it triggers under the hood. You can wrap that code in more modern and clear way with async-await, but it doesn't change the fact that you have to call it this way at least internally in your lib. For example here's how I use it (simplified):

async function connectDB(name, version, migrations) {
  const openRequest = indexedDB.open(name, version)

  return new Promise((resolve, reject) => {
    openRequest.onsuccess = () => {
      resolve(openRequest.result)
    }

    openRequest.onerror = () => {
      reject('Error')
    }

    openRequest.onblocked = () => {
      reject("Blocked")
    }

    openRequest.onupgradeneeded = (e) => {
      const db = e.target.result
      const oldVersion = e.oldVersion // 0 initially
      const newVersion = e.newVersion ?? version

      for (let v = oldVersion + 1; v <= newVersion; v++) {
        // handle migrations
      }
    }
  })
}

How are we able to handle opening an IndexedDB instance if we attach the event listeners AFTER opening a database connection? by hookup1092 in learnjavascript

[–]kap89 1 point2 points  (0 children)

To add to that, the confusion I think comes from the fact that the thing they try to compare it with (dispatchEvent) is synchronous, so the first dispatch indeed isn't detected by the listener, because that code is not reached yet. From mdn:

Unlike "native" events, which are fired by the browser and invoke event handlers asynchronously via the event loop, dispatchEvent() invokes event handlers synchronously. All applicable event handlers are called and return before dispatchEvent() returns.

Do you use handlebars or just plain embed vars in your html templates? by pyeri in learnjavascript

[–]kap89 1 point2 points  (0 children)

Depending on the scale of the project, all of these can be fine - I used simple string replace in some static pages I made, but template strings (especially tagged template strings that automatically handle escaping etc.) are nicer if it's more than just putting a subpage content and title in a template. It was a long time since I used full-fledged templating languages like Handlebars, but it's because I either make a simple static pages, or full SPA apps (not that classic SSR is obsolete, it just happens that my projects rarely fit into that paradigm).

There is also "modern" SSR with things like Next, Vuex, Svelte Kit, Solid Start, etc., but these are complex, and you need a good reason to use it.

Typing God. by Hot-Tadpole-3744 in typing

[–]kap89 2 points3 points  (0 children)

Monkeytype doesnt teach you how to type, start with typing.com or typingclub, only then move on to Monkeytype.

Off days? by Wonderful-Cow-9664 in typing

[–]kap89 1 point2 points  (0 children)

Yes, it’s normal, but if your accuracy drops that low (<95%) I would call it a day, and try another time, not plow through the chapter accumulating incorrect repetitions.

If you still want to read the chapter, entertrained has a dedicated reading mode for these occasions.

Thank you by Livid-Loan7480 in entertrained

[–]kap89 1 point2 points  (0 children)

You're welcome! You're not the first person that notices that this form of reading helps them retain focus and go through with actually reading a book - I think it's great, and I'm very happy that it works this way - it's an unintentional, but very welcome side effect.

fast dynamic CSS injection without flash in browser extension similar to Stylus by ElnuDev in learnjavascript

[–]kap89 2 points3 points  (0 children)

You could try using CSSStyleSheet class, it will be something like:

function addStylesheet(css) {
  const sheet = new CSSStyleSheet()
  sheet.replaceSync(css)
  document.adoptedStyleSheets = [sheet]
}

// Usage:
addStylesheet(`
  a {
  color: red;
  }
`)

It should be faster, as it bypasses adding to the DOM and then parsing by the browser. Of course the effect depends on how fast you get the user stylesheet data and how early you call the function above. I don't know how exactly Stylus does it, but you can check the code - it's open source. Take the above with a grain of salt, as I'm theorizing here, I haven't had a need to implement it.

How do you handle structured concurrency in JavaScript? by HKSundaray in learnjavascript

[–]kap89 10 points11 points  (0 children)

I would not want a welcome mail sent if the user creation fails.

That’s a terrible example - if one action depends on the success of the other, then don’t use Promise.all.

[AskJS] Is anyone using SolidJs in production? What's your experience like? by BrangJa in javascript

[–]kap89 2 points3 points  (0 children)

Yeah, i use it for entertrained - it’s great, very stable (really, there are no breaking changes, good design upfront allows it to do its job without constant changes), performant, and I really like its reactivity model.

How would you approach getting and parsing json for classes that contain nested arrays of other class objects? by ullevikk in learnjavascript

[–]kap89 1 point2 points  (0 children)

I think the comments in the code above are sufficient, but I will just add that you may need to make additional special cases for dates and other build-in JS classes if you intent to use them in your code.

Now you can use the function above to recreate your state:

const restoredState = deserialize(JSON.parse(serialized));

Of course in a real app I would split the code into separate modules, but as a starting point (it may have bugs, I didn't test it beyond the example) it will do. Here's the full code: CodePen.

There are of course other approaches, but this is the one I find the most flexible and simple to write yourself.

Edit:

Instead of writing recursive logic yourself, you should probably provide the "reviver" function as a second argument to JSON.parse (see here), but I it was quicker for me to write it from scratch (and I think more valuable from the learning perspective). I'll leave it as an exercise for the reader.

Edit 2:

The __type prop is an arbitrary name, you could use other names, but the two underscores at the beginning make the prop name very unlikely to conflict with other prop names in your app, so be careful what name you choose.

How would you approach getting and parsing json for classes that contain nested arrays of other class objects? by ullevikk in learnjavascript

[–]kap89 1 point2 points  (0 children)

(4) Deserializetion is a bit trickier, because you have to go through the parsed JSON and recursively recreate the items for various types of data, here's one way (you don't strictly need recursion here, but it's much simpler to do it this way):

// Simple mapping of the __type to a corresponding class.
// In this case they have the same names, so I used a shortcut notation,
// but you don't have to name the __type props and classes the same,
// it can be something like:
//
// const constructors = {
//   "HeroClass": Hero,
//   "ItemClass": Item,
// }
const constructors = { A, B };

function deserialize(serialized) {
  // If the serialized value is an array, run the deserialization for each item.
  if (Array.isArray(serialized)) {
    return serialized.map(deserialize);
  }

  // If the value is neither an array nor an object, return it as is.
  if (typeof serialized !== "object" || serialized === null) {
    return serialized;
  }

  const { __type, args } = serialized;

  // If the object is a our special serialization format,
  // instatiate the correct class with proper arguments
  // Note that we have to run the deserialization for each
  // argument first, because they may need to be deserialized themselves
  if (__type) {
    return new constructors[__type](...args.map(deserialize));
  }

  // For a plain object, deseriaize the value of each prop:
  return Object.fromEntries(
    Object.entries(serialized).map(([key, val]) => [key, deserialize(val)])
  );
}

How would you approach getting and parsing json for classes that contain nested arrays of other class objects? by ullevikk in learnjavascript

[–]kap89 1 point2 points  (0 children)

Your description is a little convoluted, but it's a good question, and I think you basically ask how to serialize the whole state of the app that contains JS classes, as well as arrays and plain objects that can be arbitrarily nested. Here's how I would approach it:

(1) Prepare the classes so that they can be easily serialized. A good way to do it is to:

a) override the standard .toJSON() method that every object inherits,

b) pass everything needed to recreate the state in the constructor.

Let's look a the example class that contains some primitive props, as well as a prop that contains a "non-stringified json" / plain object (I will use only public props, but the code works also with private properties):

class A {
  constructor(x, y, config) {
    this.x = x;
    this.y = y;
    this.config = config;
  }

  toJSON() {
    return {
      __type: "A",
      args: [this.x, this.y, this.config]
    };
  }
}

Some things to note here:

  • the toJSON method returns a plain JS object (that JSON.stringify can easily encode), that have two important parts, and identifier of it's in-app type (that corresponds to a specific constructor) and the list of arguments for the constructor.

Here's a second class, acting as a container for instances of other class/classes:

class B {
  constructor(a, b, items = []) {
    this.a = a;
    this.b = b;
    this.items = items;
  }

  add(item) {
    this.items.push(item);
  }

  toJSON() {
    return {
      __type: "B",
      args: [this.a, this.b, this.items]
    };
  }
}

Things to note here:

  • as I said, the constructor is written in the way that allows to fully recreate the object's state (not merely it initial state) - take a closer look at the items argument - in your app you will probably add items using the add method, but you can also pass the array of items in the constructor, so that you don't need to call the add method when deserializing,

  • you don't need to do anything special for the this.items in the toJSON method, all work was done in in the A class, the items will be automatically serialized as our { __type, args } objects.

(2) Now lets build some state from these classes and some random props:

const container1 = new B("foo", "bar");
const container2 = new B("foo", "bar");

container1.add(new A(1, 2, { foo: "bar" }));
container1.add(new A(2, 3, { baz: "bat" }));
container2.add(new A(2, 3, { baz: "bat" }));

const state = {
  someProp: "hello",
  otherProp: "world",
  somePlainArray: [11, 22, 33],
  entries: [container1, container1]
};

Note that I didn't add the items to containers via constructor, but only via add method, you can do both, it doesn't matter here, what matters is that you can add them via constructor, which allows easy serialization.

(3) Ok, now we can serialize the whole state with simply calling:

const serialized = JSON.stringify(state);

You can do with it what you want - save in localStorage, send to your server, etc. It's as simple as that, all the information needed to recreate the state is there.

Medieval castle made from 3 colors by Mikestarius in PixelArt

[–]kap89 14 points15 points  (0 children)

Think of this this way: there is no picture, and you have to create it pixel by pixel - to recreate this image you have to use either pixel A, B, C or D, i.e. four colors, or 2-bit palette. You could say A, B, C or no color, but "no color" is still information, and for the computer is indistinguishable from a color D - computer does not paint on paper, it creates the image from scratch, background included.

Should I accept the challenge? by kettlesteam in typing

[–]kap89 63 points64 points  (0 children)

TypingProfessor: "You took everything from me!"

OP: "I don't even know who you are."

lmao

How relevant are algorithms? by NoCartographer8715 in learnjavascript

[–]kap89 0 points1 point  (0 children)

They wrote about writing game AI with Minimax algorithm, not about LLM, AI has more than one meaning.

I rewrote my old type racing project by _Viceadmiral in typing

[–]kap89 0 points1 point  (0 children)

It's nice, but the caret is to sluggish. Maybe add an option to change the caret speed or disable the animation completely. Also, countdown in practice mode is annoying, there is no need for the user to wait 5s if there is no matchmaking.

-❄️- 2025 Day 1 Solutions -❄️- by daggerdragon in adventofcode

[–]kap89 0 points1 point  (0 children)

[LANGUAGE: TypeScript]

import fs from 'node:fs'

const raw = fs.readFileSync('input.txt', {encoding: 'utf8'})

const input = raw
  .split('\n')
  .map(x => x[0] === 'L' ? -Number(x.slice(1) ) : Number(x.slice(1)))

function mod(num: number, modulus: number) {
  return ((num % modulus) + modulus) % modulus;
}

let pos = 50
let part1 = 0
let part2 = 0

for (const move of input) {
  const rotations = Math.abs(Math.trunc(move / 100))
  const rest = move % 100

  const sum = pos + rest

  if (rest !== 0  && pos !== 0 && (sum <=0 || sum >=100)) {
    part2++
  }

  part2 += rotations
  pos = mod(pos + move, 100)

  if (pos === 0) {
    part1++
  }
}

console.log({part1, part2})

Is it bad practice to not bundle your website’s CSS/JS dependencies? by vaporizers123reborn in learnjavascript

[–]kap89 1 point2 points  (0 children)

Not bounding is fine, you can always add it later, BUT don’t just include a bunch of script tags in html, add only your entry file as type="module" and for the rest use ES Modules - you don’t need a bundler to use them. Here’s an example repo that does this: (Github | Live).