The localStorage retrieval function is returning a null value for getItem

I successfully incorporated a theme switcher into my app, enabling users to toggle between different theme/variable.scss files using an on/off switch in the interface.

However, I encountered an issue with storing and retrieving user preferences. While I managed to save the choice to local storage using setItem, I struggled to retrieve it upon refresh/navigation or default to the standard theme if no preference existed.

In my AppComponent.ts file:

export class AppComponent implements OnInit {
  currentTheme: string;
  constructor( @Inject(DOCUMENT) private document) {
  }


  ngOnInit() {
    if (localStorage.length > 0) {
      this.currentTheme = JSON.parse(localStorage.getItem(localStorage.localTheme));
    } else {
      this.currentTheme = 'Standard contrast';
      this.document.getElementById('theme').className = 'standard-theme';
    }
  }

  handleThemeChange(event) {
    if (this.currentTheme === 'Standard contrast') {
    this.document.getElementById('theme').className = 'high-contrast-theme';
      this.currentTheme = 'High contrast mode';
    } else {
    this.document.getElementById('theme').className = 'standard-theme';
      this.currentTheme = 'Standard contrast';
    }
    localStorage.setItem('localTheme', this.currentTheme);
  }

}

The problem arises when trying to update currentTheme based on what is retrieved from localStorage.localTheme. Despite the data being returned as expected, currentTheme ends up being null during debugging.

UPDATE:

this.currentTheme = JSON.parse(localStorage.getItem(localStorage.localTheme));

This particular line seems to be causing the issue. Even though (localStorage.localTheme) returns a value, this.currentTheme remains null. Any guidance on resolving this would be greatly appreciated! Thank you!

Answer №1

When storing the localTheme in local storage, ensure it is saved as an object and not just a string. Avoid parsing it unnecessarily.

Consider using:

this.currentTheme = localStorage.getItem(localStorage.localTheme);

Answer №2

Experience the power of using a getter and setter to access this.localTheme

get localTheme() {
    return JSON.parse(localStorage.getItem('localTheme'));
}

set localTheme(val) {
    localStorage.setItem('localTheme', JSON.stringify(val));
}

Answer №3

Give this a shot

let currentStyle = this.currentTheme;
localStorage.setItem('themePreference', currentStyle);

Additionally, try

console.log(typeof this.currentTheme)
to determine its data type

Answer №4

After researching the API update, @Heretic Monkey's solution was spot on. I managed to make it work using the following code:

  ngOnInit() {

    if (localStorage.length > 0) {
      this.currentTheme = localStorage.getItem("localTheme");
      const themeClass = this.currentTheme === 'Standard contrast' ? 'standard-theme' : 'high-contrast-theme';
      this.document.getElementById('theme').className = themeClass;
    } else {
      this.currentTheme = 'Standard contrast';
      this.document.getElementById('theme').className = 'standard-theme';
    }

  }

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

Implementing a feature in Typescript/React component that provides autocomplete functionality

Currently, I have developed a TypeScript and React component that has been published on NPM. My goal is to enable IntelliSense to autocomplete React props for this component. While I typically use JSDoc for plain React components, it does not seem to work ...

Error in Angular 9 Component Test: Unable to locate export named 'ngbNav'

I'm encountering an issue with a modal component that I need to test. Every time I try running the test, it gives me this error: "Export of name 'ngbNav' not found". Any suggestions on how to resolve this would be greatly appreciated. Error ...

Update the fetch options type to include object as a valid body value

In the standard fetch() function, the BodyInit_ type restricts the assignment of objects to the body property. I am looking to create a custom wrapper for fetch that maintains the same signature as fetch, but allows the second argument (options) to includ ...

What is the best way to exclude a particular subtype or property?

Is there a way to exclude a specific nested property? Let's take a look at an example. interface ILikes { article: string, page: string, userId: number | string, } interface IUserData { userName: string, isAdmin: boolean, ...data, ...

Is it possible to target an element using the data-testid attribute with #?

Is there a shortcut for selecting elements with the data-testid attribute in playwright-typescript? await page.locator("[data-testid='YourTestId']").click() I attempted to use await page.locator("[data-testid='YourData-testid ...

Define variables using specific class components only

Consider a scenario where we define a class as follows: class House { street: string; pools: number; helicopterLandingPlace: boolean; } Now, I have created a service to update my house. putHouse(house: House) { // some put request } How ...

Could directly destructure parameters upon typing be an option?

Is there a way to create destructured parameters with optional typing in TypeScript? For instance, I am trying to make the following function callable without requiring any parameters. const func = ({param}: {param?: boolean}) => {}; Currently, TypeS ...

Why is Angular ng-block-ui not functioning properly in Angular 7?

Within my app.module.ts file import { BlockUIModule } from 'ng-block-ui'; imports: [ BrowserModule, BlockUIModule.forRoot(), ] Inside the dashboard component: import { BlockUI, NgBlockUI } from 'ng-block-ui'; export class Da ...

What are the best ways to utilize .svg images for native script splash screens, backgrounds, icons, and buttons?

I am interested in replacing the .png files I previously used for my native script android app with .svg files. My goal is to utilize svg images for splash screens, backgrounds, icons, and buttons. Thank you! ...

Function that handles passing an Angular Dialog

I am facing a problem with my components. One of them requires an input with an array object that looks like { name: 'buttonname', click: () => {}}. I need to pass a function to the click property to open the dialog component. I am unsure of ...

The Tanstack react-table feature is limited in its ability to output tsx from the cell

Currently conducting a test on Tanstack react-table library using React and TypeScript. It appears that I am encountering an issue with returning tsx/jsx from the cell function of ColumnDef: https://i.sstatic.net/d5X3y.png Is there something crucial that ...

Issue with Angular2 Router: No routes were found for the specified path ''

I have set up the Angular2 Router in the following way: import { provideRouter, RouterConfig } from '@angular/router'; import { Page2} from './page2'; const routes: RouterConfig = [ { path: 'page2', component: Page2 } ]; ...

unable to redirect through handlerror

I am attempting to redirect to an error component when the response data contains a "401" error. Below is my code snippet, but it seems that it is not properly handling the error. I have tried redirecting to an external URL without success. Any guidance wo ...

What would be the best TypeScript target and libs to utilize in a transpiler-free Node.js project?

If I am running a TypeScript Node.js project with the command tsc && node build/index.js (where tsc builds into build/ and index.ts is in the project), what values should be used in lib and target in tsconfig.json to ensure access to the latest TypeScrip ...

Is there a way to access the value of an IPC message beyond just using console log?

I am developing an app using electron and angular where I need to send locally stored information from my computer. I have successfully managed to send a message from the electron side to the angular side at the right time. However, I am facing issues acce ...

"Debating Angular: Comparing the Use of Getters and Methods in

To prevent cluttering the *ngIf directive with logic directly in the template. <div *ngIf="a === 3 && b === 'foo'"></div> I typically create a custom method like this: public isOk(): boolean { return a === 3 & ...

Handling authentication errors in Angular 2 using @ngrx/effects

Everything is functioning smoothly with @ngrx/store and effects, but now I'm realizing that there will be a significant number of API calls (in effects). If any of those calls returns a 401 error, I need to redirect the user to the login page. The dil ...

Transferring information between Puppeteer and a Vue JS Component

When my app's data flow starts with a backend API request that triggers a Vue component using puppeteer, is there a way to transfer that data from Backend (express) to the vue component without requiring the Vue component to make an additional backend ...

The ngModel for a text box does not store the accurate value when the Google Places Autocomplete API is being utilized

I am trying to implement the Google Places Autocomplete API with a textField in my project. The goal is to have city suggestions appear as I type in the textField. Currently, I have bound my textField to a variable called "searchFieldValue" using ngModel. ...

Troubleshooting Issue: Data not appearing on Angular frontend when fetching from Laravel API

Utilizing Laravel for the back end and Angular for the front end development. The code segments related to Angular can be found in employee.component.ts file: import { Component, OnInit } from '@angular/core'; import { DataService } from 'sr ...