the window.matchMedia event listening for the dark color scheme preference fires just a single time

My goal is to automatically change the theme mode (light/dark) based on the user's device preference using addEventListener. However, I am facing an issue where the event is only triggered once. I am currently working with Ionic and Angular.


Angular CLI: 14.2.3
Node: 16.17.0
Package Manager: npm 8.19.1
OS: win32 x64

Angular: 14.2.3
... cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                         Version
---------------------------------------------------------       
@angular-devkit/architect       0.1402.3
@angular-devkit/build-angular   14.2.3
@angular-devkit/core            14.2.3
@angular-devkit/schematics      14.2.3
@schematics/angular             14.2.3
rxjs                            6.6.7
typescript                      4.7.4

Ionic version: 6.20.1

In service.ts:


setListenerTheme(): void {
    window.matchMedia('(prefers-color-scheme: dark)').onchange = (e) => {
      console.log("Listening for theme changes")
      const buttonToggleTheme = document.querySelector('#themeToggle');

      buttonToggleTheme.toggleAttribute('checked');
    };
}

toggleTheme(event: any): void {
    this.dark_mode = event.detail.checked;
    document.body.classList.toggle('dark', event.detail.checked);
}

In app.component:


export class AppComponent implements OnInit {

  constructor(
    private userService: UserService,
  ) {}

  ngOnInit(): void {
    this.userService.setListenerTheme();
  }

}

Answer №1

Consider using addEventListener in place of onChange. This approach worked effectively for me on both my ionic 5 and ionic 6 applications. Here is an example implementation:

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
prefersDark.addEventListener('change', (mediaQuery) => {
      this.toggleDarkMode(mediaQuery.matches);
    });

Ensure that your logic is based on the boolean value of mediaQuery.matches, which can be either true or false, indicating whether dark mode is activated or deactivated. If this solution does not resolve your issue, please provide a more detailed explanation of the problem. For instance, when you say "firing once," do you mean "the first time dark mode is enabled" or "the initial switch between dark and light modes"? Additionally, test the functionality across various devices and observe different outputs.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for a Node.js/Express server to securely handle all UTF-8 characters?

At the moment, my setup involves a node server running Express that is connected to a PostgreSQL database with UTF-8 encoding support. In terms of frontend, I'm using Angular which has built-in measures for preventing unsafe injection. I am curious i ...

Validation for Angular nb-step and nb-select components

Looking at this code snippet: <nb-stepper #stepper orientation="horizontal"> <!-- **************** STEP N1 **************** --> <nb-step [label]="labelOne"> <ng-template #labelOne>Area</ng-temp ...

Implementing a Map in Typescript that includes a generic type in the value

Here is a code snippet I am working with: class A<T> { constructor(public value: T) {} } const map = new Map(); map.set('a', new A('a')); map.set('b', new A(1)); const a = map.get('a'); const b = map.get(& ...

unable to transform this string into an object

https://i.sstatic.net/O46IL.pngWhy am I encountering difficulties converting this string into an object? Any assistance on resolving this error would be greatly appreciated. onSignup(data:any){ localStorage.setItem('users',JSON.string ...

Using conditional statements to localize in Angular

In my Angular application, I am utilizing i18n for internationalization purposes. When it comes to HTML, I use i18n="@@<unique_Id>" and for dynamic elements defined in TypeScript class files, I use $localize. For example: this.buttontext = ...

Encountering a roadblock while installing Ionic for Android development

Every time I attempt to execute the command npm install -g cordova ionic, it remains stuck for several hours. https://i.sstatic.net/E2nGY.png ...

Angular Material Datatables - Issue with Paginating Data from Firestore

Data has been retrieved from Firestore and transformed into an Observable array with the InvoiceItem type. The data loads correctly onto the datatable, but there seems to be an issue initializing the paginator with the array's length. This could poss ...

Remove the Prisma self-referencing relationship (one-to-many)

I'm working with this particular prisma schema: model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("p ...

What are some strategies for locally developing Angular 7 libraries that have dependencies on one another? (Troubleshooting npm linking)

I am managing two Angular library NPM packages: A contains basic components A-BC includes components that enhance the ones in A, with additional features to interact with the BC library Some components in A-BC are imported from A like import { MyThing } ...

Is it possible for TypeScript to convert objects while preserving type annotations?

Apologies for my limited English skills, but I will do my best to explain my dilemma. I am looking to create a TypeScript function that can replace the keys of an Object. For example: interface Target { name: string; ID: number; } // The functio ...

Angular MDBootstrap formatting disappears upon refresh of the page

I am currently utilizing the MDBootstrap package for Angular in my project, specifically focusing on styling buttons within a page I am developing. Upon initial loading of the page, the button styles are successfully applied. However, upon reloading the p ...

TypeScript interface designed to capture objects containing a flexible number of values

In my possession is an object that looks like the following: { "0001": "a", "0002": "b", "0003": "c", ... } Is it possible for me to create a TypeScript interface that accurately represents this type? ...

Leveraging constructors for injecting dependencies in Angular is a key practice for enhancing modularity and maintainability

After reviewing the Angular Official documents and various blogs, I noticed that there are two different syntaxes for Dependency Injection (DI) when used within the constructor. Sometimes this is utilized, while other times it is not. This leads to the que ...

Tips for incorporating Google Docs into a web application to enable previewing, editing, and saving functionality

Incorporating Google Docs into a web application (Angular 10) for previewing, editing, and saving is my goal. I have documents stored on my server and would like to utilize Google Docs to preview these files, whether they are stored on Amazon S3, Azure, o ...

The creation of a Firebase user account with the specified email and password

I'm currently facing an issue while creating a new user with email and password using firebase authentication. The problem arises when I try to access the displayName from the returned async call before the updateProfile function, as it returns a null ...

Implementing debounceTime in Angular can be done by using the debounceTime operator

I am currently working on implementing the debounceTime functionality in an autocomplete feature. My goal is to use debounceTime to minimize the number of server calls. After researching, I found 3 possible solutions which I have included snippets of belo ...

Internationalization in Angular (i18n) and the powerful *ngFor directive

Within my Angular application, I have a basic component that takes a list of strings and generates a radio group based on these strings: @Component({ selector: 'radio-group', templateUrl: `<div *ngFor="let item of items"> ...

"If the property is not undefined, use a conditional type to retrieve the numerical index from it, otherwise display a message indicating that there is

Here is a snippet of code I am working with: type Numbers = [3,65,2,7,3,99,23,555]; interface Options { options?: Numbers; } type FilterOption = Options['options'] extends undefined ? undefined : Options['options'][number]; I am tr ...

What is the reason behind starting certain scripts using "npm start x" while others only require "npm x"?

Within the package.json file, I have included a section dedicated to defining scripts for various tasks: "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build --prod", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, ... When lau ...

List out the decorators

One query is bothering me - I am attempting to create my own version of Injectable and I need to determine if a specific decorator exists in my Class. Is there a way to list all decorators of a class? Let's take the example below. All I want to know i ...