Live data from Hacker News

JavaScript Views, the Hard Way – A Pattern for Writing UI

github.com

121–130 of 141 posts

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#121

Earlier quoted context omitted.

Depends on what you mean by sanitising. If you mean filtering out undesirable parts of a document (e.g. disallowing element or onclick attribute), that should normally be done on the server, before storage. If instead you mean serialising , writing a value into a serialised document: then this should be done at the point you’re creating the serialised document. (That is, where you’re emitting the HTML.) But the golde…

What's wrong about filtering before saving, is that if you forget about one rule, you have to go back and re-filter already-saved data in the db (with some one-off script). I think "normally" we should instead filter for XSS injections when we generate the DOM tree, or just before (such as passing backend data to the frontend, if that makes more sense).

Don't forget that different clients or view formats (apps, export to CSV, etc) all have their own sanitization requirements.

Sanitize at your boundaries. Data going to SQL? Apply SQL specific sanitization. Data going to Mongo? Same. HTML, JSON, markdown, CSV? Apply the view specific sanitizing on the way.

The key difference is that, if you deploy a JSON API that is view agnostic, that the client now needs to apply the sanitization. That's a requirement of an agnostic API.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#122

Earlier quoted context omitted.

Posts are sanitized on the server side. This is client side code.

Although appealing, that’s an extremely bad idea, when you’re limited to JavaScript. In a language with a better type system, it can be only a very bad idea. The problem is that different contexts have different escaping rules. It’s not possible to give a one-size-fits-all answer from the server side. It has to be done in a context-aware way. Field A is plain text. Someone enters the value “Alpha & Beta”. Now, what d…

You're unnecessarily complicating this. The server is aware of what fields are HTML so it just encodes the data that it returns like we've been doing for 30 years now. If your point is that this approach is only good with servers that you trust, then that's useful to point out, although we kind of already are vulnerable to server data.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#123
post #50

Earlier quoted context omitted.

what are those 6 places? how were they updated before?

You have a card with a name, when you click it a detail popup opens and the name is in there. There's also a delete button saying "Delete ", which pops up a confirm dialog and the name is in there, too. When you update the name you have to update all those places. The alternative is there's a canonical name variable, and it's rendered in all those places. To update the name, you just update that variable and "re-rend…

yeah okay, I agree.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#124

Earlier quoted context omitted.

> use the DOM element value/textContent/checked/etc as the only source of truth How do you manage redundant state? For example a list with a "select all" button, then the state "all selected"/"some selected"/"none selected" would be duplicated between the "select all" button and the list of elements to select. This is the fundamental (hard) problem that state management needs to solve, and your proposal (along with t…

They could always fall back to storing a value in a hidden element in the worst case. All/some/none selected is often done with an indeterminate state checkbox https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/... that can represent all three states. Maybe I don't understand the problem you are talking about.

As soon as you need to store some state elsewhere you can store it in another suitable form (there's often some state not visually represented). I seem to recall jQuery stored state on a POJO (plain old JavaScript object) within a JavaScript variable of an element.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#125

Earlier quoted context omitted.

Reactive view libraries exist to hide those details. I think the OP is proposing that the benefit of reactive views/state isn't worth the cost and complexity.

It is absolutely worth the cost and complexity. The cost and complexity of building a web application using some home grown vanilla JS system will end up being a horrible engineering decision most of the time. There have been zero times in my career where I thought "hmm, maybe we shouldn't have build this thing in React and let's just go back to page scripts." If you're building landing pages and websites, then okay.…

That's way too dependent on context to say the cost is always worth the complexity.

On a team that is experienced in react, or a project that is heavily dependent on client side rendering react (or similar) make sense.

On a team that is more backend focused or a project that is CRUD heavy and generally rendering state that persists on the server, it could very well make sense to lean on server rendered HTML with small bits of JS scripts for interactivity.

We as an industry way over tilted on client-side rendering. If you're building Facebook or Figma or Discord, sure maybe CSR is a must. For most websites you don't need much CSR though, and if you're only using it for small bits of interactivity you may be better offer foregoing the complexity of a framework and taking responsibility for the full render pipeline.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#126

Earlier quoted context omitted.

I feel like you completely misinterpreted their comment. They replied to a comment saying that state should not be centralized. They said that if the state decentralized (as in held by individual child components) it's difficult to coordinate between sibling and parent/child components. It seems like you're saying that it's easy to do UI with a centralized state, therefore agreeing with them whilst having the tone of…

The parent comment said: This approach is simple but does not scale and You need separation between components and data. That is garbage and is what I replied to. I completely understand why JavaScript developers would fail to read this as such as most JavaScript developers are wholly incapable of programming, a forest for the trees problem.

> JavaScript developers would fail to read this

> You need separation between components and data

this is an universal way to do UI, in fact only javascript developers (out of curiosity, are you one?) would even argue against it, because "use the platform", vanila, simple... blabla, or you know, "incapable of programming" and thinking in terms of data flow as opposed to platform intricacies

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#127

Earlier quoted context omitted.

What's wrong about filtering before saving, is that if you forget about one rule, you have to go back and re-filter already-saved data in the db (with some one-off script). I think "normally" we should instead filter for XSS injections when we generate the DOM tree, or just before (such as passing backend data to the frontend, if that makes more sense).

Don't forget that different clients or view formats (apps, export to CSV, etc) all have their own sanitization requirements. Sanitize at your boundaries. Data going to SQL? Apply SQL specific sanitization. Data going to Mongo? Same. HTML, JSON, markdown, CSV? Apply the view specific sanitizing on the way. The key difference is that, if you deploy a JSON API that is view agnostic, that the client now needs to apply th…

Please don’t use the word sanitising for what you seem to be describing: it’s a term more commonly used to mean filtering out undesirable parts. Encoding for a particular serialised format is a completely different, and lossless, thing. You can call it escaping or encoding.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#128

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

> use the DOM element value/textContent/checked/etc as the only source of truth How do you manage redundant state? For example a list with a "select all" button, then the state "all selected"/"some selected"/"none selected" would be duplicated between the "select all" button and the list of elements to select. This is the fundamental (hard) problem that state management needs to solve, and your proposal (along with t…

I don't think I understand your question, or its just a poor example.

Regardless of design pattern or framework; the state all/some/none of a list, should practically never exists as separately updated state variable. Whenever its required you need to derive it.

    noneSelected = !querySelectorAll("input:checked")

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#129

This might be heresy to many JS devs, but I think 'state' variables are an anti-pattern. I use webcomponents and instead of adding state variables for 'flat' variable types I use the DOM element value/textContent/checked/etc as the only source of truth, adding setters and getters as required. So instead of: /* State variables */ let name; /* DOM update functions */ function setNameNode(value) { nameNode.textContent =…

I feel you, but isn't the state of truth for most websites supposed to be whatever is in the database? The example TODO List app, each TODO item has stuff in it. That's the source of truth and I believe what is trying to be solved for for most frameworks. In your example, where does name come from originally? Let's assume it's a contact app. If the user picks a different contact, what updates the name, etc... If the…

The requirements are a bit too vague so i'm guessing here.

The design were talking about is mutating local state to update the view.

Unchanging variables (like a name from a db) are provided on construction and not relevant.

Selecting a new contract to 'open' creates a new contract element. No need to update the existing element.

----

If you're talking about "if I edit here it updates there as well", than I believe those are gimmicks that reduce usability.

If I understand your example correctly: a multi-contract view where the user updates a 'name' in both. IMO its a better UI to explicitly have the name: _outside_ the contract elements. The contract element can do nameInput.onchange =(e) => {...} when constructed to update itself.

Re: JavaScript Views, the Hard Way – A Pattern for Writing UI

#130

Earlier quoted context omitted.

> (...) I think 'state' variables are an anti-pattern. I use webcomponents (...) It's unclear what you mean by "state variables". The alternative to state variables you're proposing with webcomponents are essentially component-specific state variables, but you're restricting their application to only cover component state instead of application state, and needlessly restricts implementations by making webcomponents m…

"State variables" is a section in the original article. It shows a variable in the view, "name", that holds the value separate from the DOM. setName(value) first checks the local state variable, and if different the value is both written to the state variable and the DOM. The GP's pattern uses getters and setters to directly read and write to the DOM, skipping the need for a local variable entirely.

I have an approach that I think no one else has tried before. Looking for someone to endorse me on arxiv so I can publish it.
Post reply on HN