Typescript encountering difficulty in accessing an array saved in sessionStorage

Imagine you have an array stored as a string in session storage, and you need to retrieve it, add an element, and then save it back.

trackNavHistory = (path: String) => {
    let historyArr : Array<String> = sessionStorage.getItem("navHistory")?.split(",");
    historyArr.push(path)
    sessionStorage.setItem(JSON.stringify(historyArr));
  }

The goal is to have historyArr as an array of strings fetched from sessionStorage.

However, the issue arises with the error message:

Type 'string[] | undefined' is not assignable to type 'String[]'.
Type 'undefined' is not assignable to type 'String[]'

This prevents setting the item back correctly.

An alternative attempt was made with the code snippet:

trackNavHistory = (path: String) => {
    let historyArr : Array<String> = JSON.parse(sessionStorage.getItem("navHistory"));
    historyArr.push(path)
    sessionStorage.setItem(JSON.stringify(historyArr));
  }

Argument of type 'string | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'.ts(2345)

Answer №1

First and foremost, it is crucial that your getter and setter functions are inverse operations of each other - avoid manipulating the JSON data recklessly.

Furthermore, what you are experiencing is not a system "crash" but rather an error from the TypeScript compiler. TypeScript is simply pointing out that you need to handle cases where there might be no value present (the return type of getItem is string | null, while you require a string type).

To resolve this issue:

  1. We begin by retrieving the session data.
  2. We then ensure that the data is not null or undefined.
  3. If we have valid data, we parse it and add it to an array.
  4. Subsequently, we append the new path to this array, which could be empty if there was no previous session data.
  5. Finally, we update the session data with the modified array.
const trackNavHistory = (path: String) => {
  const data = sessionStorage.getItem("navHistory");
  let historyArr = [];
  if (data) {
    historyArr = JSON.parse(data);
  }
  historyArr.push(path);
  sessionStorage.setItem("navHistory", JSON.stringify(historyArr));
}

Try it on TypeScript Playground

Answer №2

In typical TypeScript coding practice, the standard way to define a variable of type string is to use the keyword string with a lowercase initial letter.

It is recommended to utilize JSON.stringify before storing data in sessionStorage, and utilize JSON.parse to retrieve the array data from JSON format.

The variable historyArr is declared as an array that can only hold strings with the syntax

let historyArr : Array<String>
. However, since sessionStorage.getItem can return either a string or null, and JSON.parse(null) === null, TypeScript raises an error when trying to assign the result of this operation (
JSON.parse(sessionStorage.getItem("navHistory"));historyArr.push(path)
) to the historyArr variable.

A more effective approach would be:

const trackNavHistory = (path: string) => {
    let navHistory = sessionStorage.getItem('navHistory');

    if (!navHistory) {
        sessionStorage.setItem('navHistory', JSON.stringify([path]));
        return;
    }

    const historyArr: Array<string> = JSON.parse(navHistory);

    historyArr.push(path);

    sessionStorage.setItem('navHistory', JSON.stringify(historyArr));
};

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

TypeScript: Seeking a mechanism akin to ReturnType<...> that specifically targets the type of the initial function parameter

Can TypeScript allow for the declaration of a ReturnType<...> that doesn't fetch the return value's type but instead retrieves the type of the first argument? type SingleArgFunction<A, R> = (arg: A) => R // incorrect - how can th ...

Ways to reset an input field when focused

Looking to implement a number input field in React that clears the initial value when the user clicks on it. While there are solutions available for text inputs, I have not come across a method for number inputs. Every attempt I make at solving this issu ...

The best approach for setting a select value and managing state in React using TypeScript

Currently, I am in the process of familiarizing myself with TypeScript within my React projects. I have defined a type for the expected data structure (consisting of name and url). type PokedexType = { name: string; url: string; } The API respon ...

Is it possible to create a Cypress report that only includes the successful test cases and excludes the failed ones?

Hello everyone, I trust you are well. Currently, I am seeking a solution to exclude failed test cases from Cypress XML report when using Junit as a reporter. The issue arises when importing test results into Jira, as failures create duplicate tests instead ...

What is the method for importing styles in Next.js without including the file extension?

I've got a project set up with Next.js, TypeScript, and SCSS. In every app/*/page.tsx or components/*/page.tsx, there's a line importing the stylesheet like import style from "styles/*/index.module.scss". I find these lines to be too lo ...

Tips for binding data to numerous dynamic controls

Implementing reactive forms in my Angular project allowed me to create a simple form for adding employee work hours and breaks. The challenge I encountered was the inability to bind data from break controls. In the .ts file export class AddAppointmentForm ...

Encountering "Object is possibly undefined" during NextJS Typescript build process - troubleshooting nextjs build

I recently started working with TypeScript and encountered a problem during nextjs build. While the code runs smoothly in my browser, executing nextjs build results in the error shown below. I attempted various solutions found online but none have worked s ...

Implementing conditional where clauses in Firestore queries with dynamic parameters

Consider this scenario: I have a dynamic filter list for my product list, and I want to send an HTTPS request to a cloud function based on the selected filters. However, when trying to set multiple conditional where clauses from that request... The multip ...

Tips for integrating a custom handler to the close icon in Material UI TextField component

In my Reactjs/Typescript project using Material UI, I have a search input component rendered with TextField. The built-in "x" icon clears the input value, but I want to create a custom handler for making an API call when the search value is deleted. I&apo ...

Having trouble integrating jQuery into an Angular CLI project

I'm trying to incorporate jQuery into my angular project created with angular cli. I followed the instructions provided on this website: To begin, I installed jQuery by running: npm install --save jquery; Next, I added type definitions for jQ ...

Using React.Fragment in VS Code with TypeScript error 2605 while having checkJs enabled

While utilizing the JS type checking feature in VScode, I encountered an issue with React.Fragment that is being linted with an error: JSX element type 'ReactElement<any>' is not a constructor function for JSX elements. Type 'ReactEle ...

After upgrading from Angular 13 to 14, the <app-root> component is failing to load. Despite no noticeable changes, the issue persists

Having upgraded my Angular 13 app to version 14, I encountered an issue where the page no longer loads properly. Despite checking the configuration and stripping down the index.html file to its basics, the issue persists - nothing seems to be working. Upo ...

Activating functions based on radio button selection in React with TypeScript

Below are the radio buttons with their respective functions: <div className="row"> <div className="col-md-4"> <label className="radio"> <input onChange={() => {serviceCalc()}} ty ...

Utilizing String.Format in TypeScript similar to C# syntax

Is there a way to achieve similar functionality to String.Format in C# using TypeScript? I'm thinking of creating a string like this: url = "path/{0}/{1}/data.xml" where I can substitute {0} and {1} based on the logic. While I can manually replace ...

One issue that may arise is when attempting to use ngOnDestroy in Angular components while rearranging user transitions

Encountered an issue recently with Angular - when the user navigates from component A to component B, component A remains active unless ngOnDestroy is triggered. However, if the user visits component B before going to component A and then leaves, ngOnDes ...

Issue encountered when attempting to import a module within the ionic framework

I encountered an issue in my project (built with the ionic-framework 3) where I included the following line to import the dialogflow module: const dialogflow = require('dialogflow'); However, when compiling, it resulted in the error message: ...

React Redux Bundle with Hot Reload Feature

Working on a project written in TypeScript with the React and Redux framework, I'm familiar with webpack and its middleware libraries for hot reloading. My question arises when considering how my TypeScript code is first converted to JSX through gulp ...

Navigating TS errors when dealing with child components in Vue and Typescript

Recently, I encountered an issue where I created a custom class-based Vue component and wanted to access its methods and computed properties from a parent component. I found an example in the Vue Docs that seemed to address my problem (https://v2.vuejs.org ...

When an input event is dispatched in a unit test, the value changes of a form are not activated

Currently, I am testing a scenario where I need to verify if a value changes on the form when input is typed in. This particular project utilizes Nrwl nx as well as jest for testing purposes. The component code snippet is as follows: export class InputNu ...

Multiple keyup events being triggered repeatedly

Currently, I am developing an Angular 4 application. Within my component's HTML, there is a textbox where users can input text. As soon as the user starts typing, I want to trigger an API call to retrieve some data. The current issue I am facing is t ...