#92 Angular data binding with arrays: Yes, it can work!

Angular is awesome. And data binding, in particular, has been a game changer for developing modern web apps. Something changes somewhere and—magically—every part of your UI that needs to respond does so. However, I’ve always struggled with one corner case: What if you’re binding to an array, and the change that occurs is that something gets added or removed, and you need to respond to the change programmatically (not just in your HTML template)? ...

September 30, 2025

#77 In-place DOM manipulation: Thorny as ever 🥀

The “highlights” feature in the poketto.me reader looks deceptively simple: select a text range, and it gets highlighted in yellow. Clicking a highlight opens a small context menu to change its color or delete it. But the implementation? Much thornier than you’d think. Why? 1️⃣ Browser selections are relative to visible text, not the underlying DOM tree of the rendered HTML. 2️⃣ A selection is defined by the text plus its start offset (characters before the selection) and end offset. 3️⃣ To do anything useful with a selection (beyond copying text to the clipboard), you have to map it back to its position in the DOM tree. 4️⃣ That “mapping” is, to some extent, impossible to get perfectly right. A selection can span multiple nodes, start and end at different levels of depth, and include irrelevant nodes. ...

September 15, 2025

#58 The occasional toast can’t hurt

Some of the designers and frontend devs I’ve worked with may remember my rants against toast notifications: “Why do I need a success message for every action? I expect things to work. Only tell me when something breaks.” But… I’ll admit it: Sometimes toasts do have their merit. Two examples from poketto.me: 🔹 Copy to clipboard (Podcast feed URL): When users click the “copy” button, the action happens instantly. But without any feedback, it feels… awkward. ...

August 27, 2025

#55 UX details sometimes make all the difference

In WebSockets: More than tech vanity, I talked about how poketto.me uses WebSockets to keep the UI in sync with async backend processes—like translating, TTS, etc. Neat? Sure. Game-changing? Probably not. Just like I asked about AI in AI is not a value proposition: where would you put that on the Business Model Canvas? It doesn’t really fit as a Value Proposition, does it? But that doesn’t mean it’s not important. Take Strava, for example. ...

August 24, 2025

#52 Object.assign(...) in JavaScript helps with asynchronous updates

In WebSockets: More than tech vanity, I talked about the implicit user value of asynchronous UIs. Today, here’s a neat little JavaScript trick I hadn’t been aware of that makes implementing them a bit easier: Object.assign(...). Here’s the situation: Your Angular frontend initially fetches a list of items from the backend. Thanks to Angular’s powerful data binding, many components reference properties of these objects. Later, the backend sends an updated version of one of these items via WebSocket. What now? ...

August 21, 2025

#51 WebSockets: More than tech vanity

As I said in Socket science isn’t rocket science, WebSockets are quite easy to use with Python + Flask + Socket.IO on the backend and Angular + Socket.IO + RxJS on the frontend. But why bother? Dealing with asynchronous requests is more of a hassle than not. And for a “boring” app like poketto.me, aren’t synchronous HTTP requests/responses good enough? Here are two use cases where, despite the app’s apparent simplicity, asynchronous backend/frontend communication adds real value: ...

August 20, 2025

#33 Mind the Gap — flex-gap!

I use flex-based layouts a lot in the #Angular frontend of poketto.me. But I never realized there’s a neat little property called gap (or flex-gap) that lets you define spacing between flex items directly. For the longest time, I worked around this with clumsy constructs where I’d set margins on child elements — and then unset them on the last child: .container { display: flex; flex-direction: column; .child { margin-bottom: 1rem; &:last-child { margin-bottom: unset; } } } ``` When really, the world could be so much simpler: ``` .container { display: flex; flex-direction: column; gap: 1rem; } ``` No more margin hacks.

August 2, 2025

#18 Socket science isn’t rocket science! 🚀 Or: WebSockets + Flask + SocketIO = ❤️

For some reason, async communication between a web app backend and the browser causes more anxiety than it should (guilty 🙋). I’ve had my fair share of headaches with WebSocket frameworks before, but for poketto.me, I tried a much simpler stack—and was pleasantly surprised: ➡️http backend: Flask ( https://flask.palletsprojects.com/en/stable/) ➡️websocket backend: Flask-Socketio ( https://flask-socketio.readthedocs.io/en/latest/) ➡️websocket frontend: socketio-client ( https://www.npmjs.com/package/socket.io-client) 🔌 Backend: Handling connections is dead simple @socketio.on('connect') def handle_connect(): _, user_id = authenticate() sid = request.sid connected_clients[user_id] = sid 📤 Sending data to a connected client sid = connected_clients.get(user_id)\ if sid: socketio.emit('message', { 'message_type': 'save_changed', 'data': { 'id': save_id, 'state': 'archived' } }, to=sid) #### **🖥️ Frontend: Receiving messages is just as easy** const socket = io(environment.WS_BASE_URL, { ...

July 18, 2025

#17 Designing for mobile after the fact is painful

I’ll admit it: when I built the frontend for [poketto.me, I focused mostly on desktop browsers—except for the reading experience, which was always meant to be mobile-first. But optimizing the rest of the UI for smaller screens later on? A real hassle—and one that could’ve been avoided had I truly embraced mobile-first design from the start. Here are a few key lessons the hard way taught me: 📱 *Thumb-friendly design matters* The Rule of Thumbs is real: ...

July 17, 2025

#16 Material’s tooltip interferes with touch-scrolling on mobile

As I mentioned the other day, I love Angular Material. However, I was quite surprised to discover that the matTooltip directive can negatively impact the user experience on mobile 🤯 I noticed that users couldn’t 'drag to scroll' on poketto.me on their phones (in both the Android app and the browser) when they started to drag particular elements on the screen, such as the save title images. After a lot of analysis and debugging, I discovered that the matTooltip directive, which I use to render tooltips displaying the full save title in case it is abbreviated, sets touch-action: none; on that element. This means: On a mobile device, users can't start scrolling the page with that element as an anchor. It feels totally weird! ...

July 16, 2025