Author: drweb

RxJs is the most challenging library of the Angular ecosystem because of its syntax, numerous operators, and the asynchronous mindset associated with Observables.Today, let’s see the easiest way to debug RxJs code in Angular. Now, you’ve probably done something like this at least once:service.getSomeObservable().subscribe(data => {console.log(data);});While the above works, it’s not ideal for a bunch of reasons:It forces you to subscribe to an Observable instead of using the async pipe, which is much better.It doesn’t allow you to debug what happens in that Observable before the subscriber receives the data.For instance, let’s say you inherit the following code to debug…

Read More

AI-generated image from the prompt “create signals out of observables”Signals are becoming increasingly an alternative to RxJs in Angular applications.Of course, there are the toSignal and toObservable functions to implement interoperability between Angular Signals and RxJs Observables, but what if we want to get more features than the basics?For instance, say we’d like to know if an Observable is still loading its initial data or if an error happened. Wouldn’t it be great to be able to do something like this?@if( myData.loading() ) {Loading data…} @else {{{ myData.data() }}}@if (myData.error()) {Something went wrong!}These three methods loading, data, and error, are…

Read More

A few years ago, I published a tutorial on how to do polling with RxJs and Angular. The goal was to illustrate how to retrieve and render information that gets refreshed periodically.With the latest iterations of Angular, we can simplify that approach a lot and implement a similar feature with less code, better performance, and no risk of memory leak!And we’ll be using Signals, too!First, let’s take a look at the 2020 version of my polling example:@Injectable()export class CurrencyService implements OnDestroy {private allCurrencies$: Observable;private stopPolling = new Subject();constructor(private http: HttpClient) {this.allCurrencies$ = timer(1, 3000).pipe(switchMap(() => http.get(‘http://localhost:8000/currencyInfo’)),retry(),tap(console.log),share(),takeUntil(this.stopPolling));}getAllCurrencies(): Observable {return this.allCurrencies$.pipe( tap(()…

Read More

A proxy forwarding an HTTP request to avoid CORS issues, as generated by AIIf you’ve ever encountered CORS errors in your Angular apps, this tutorial is for you!CORS stands for Cross-Origin Resource Sharing. It’s a security mechanism that allows web browsers to make controlled requests to resources on a domain different from the one serving the web page.This means if you’re serving your app on a domain “example.com” or “localhost” and your web app makes requests to “google.com” or some other domain, the web browser will make a preflight request (HTTP OPTIONS) to that other domain to ask if “example.com”…

Read More

Since version 16, Angular has been all about signals. I’ve covered how to create Signals from Observables to transition away from RxJs, but the Angular team introduced an even better option with Angular 19: The resource API.This API is experimental for now, as shown in the official documentation. This means it’s not recommended for production yet, but it’s such an exciting development that I had to write a tutorial on that topic anyway:Observables are used in many places in Angular, especially the HttpClient. Using Signals around these Observables, while doable, isn’t always obvious and brings a few extra challenges, such…

Read More

A few days ago, I was teaching Angular, and people asked me why I was doing this with my signals inside Angular services:readonly data = signal(‘value’).asReadonly();Why am I using read-only twice? Isn’t this redundant?First, let’s say I only do this:export class DataService {data = signal(‘value’).asReadonly();}Other components can inject that service, and the following is prevented, which is good if we want to ensure components can’t change the value of a Signal:export class AppComponent {data = inject(DataService).data;constructor() {// This doesn’t compile because our signal isn’t writabledata.set(“New value”);}But a developer could still break things and create all sorts of problems by doing…

Read More

Last updated: November 15, 2023. It is often useful to get the current index value inside a loop. But the index value is not immediately available in a for…of loop. For example, trying to access the index value after the current value of the iterable being looped through causes an error to be thrown: const array = [“x”, “y”, “z”]; for (value, index of array) { // Uncaught SyntaxError: Invalid left-hand side in for-loop console.log(index); console.log(value); }; The solution is to transform the iterable from a simple iterable (no nesting) into an array of arrays, in which each nested array…

Read More

January 9, 2025 When we published our advice on the simplest and best way to take some static local files and make a proper online website out of them, we recommended Netlify. That holds true. But there is some trepidation, as once in a while you’d hear a horror story about usage blowing up unexpectedly and a user being stuck with a big bill. This is a problem not isolated to Netlify, but happened there too. That’s a scary prospect for anyone, as unlikely as it may be. So I think it’s notable that Netlify announced a free plan which…

Read More

Welcome to the stylish arena where CSS Grid and Flexbox, the two titans of CSS layout techniques, face off in a duel of elegance, efficiency, and flexibility. Whether you’re a budding web designer or a seasoned developer looking to brush up your skills, understanding the differences between these two powerful layout systems is essential. So, grab your popcorn, and let’s dive into this fun and informative comparison! Round 1: The Concept Corner CSS Grid: The Architect Imagine CSS Grid as the master architect of web layouts, offering a two-dimensional system that lets you manage both rows and columns with precision.…

Read More

Last updated: November 27, 2023. Want to know if an object is empty? With an array you can do this by checking the value of its length property. But this is not possible with an object: /* Checking if array is empty */ const array = []; console.log(array.length); // 0 const arrayIsEmpty = array.length === 0; console.log(arrayIsEmpty); // true /* Checking if object is empty */ const obj = {}; console.log(obj.length); // undefined const objIsEmpty = obj.length === 0; console.log(objIsEmpty); // false The problem with the above code that leads to the incorrect result for the object is length property…

Read More