Home > OS >  prevent part of array saving to localStorage in angular
prevent part of array saving to localStorage in angular

Time:01-20

I am trying to prevent resultComment being saved into localStorage, how can I achieve that? Currently when I delete localStorage data from browser and calculate result, result gets pushed to my resultHistory array and only the result and temperatureUnit gets saved to localStorage which I want, but on the second calculation now also the resultComment gets saved. How can I prevent this or what can be done differently? Here is StackBlitz: https://stackblitz.com/edit/angular-ivy-mdhnnt?file=src/app/app.component.html,src/app/app.module.ts,src/app/app.component.ts,src/app/app.component.css

Steps to recreate problem:

  1. Clear localStorage data and refresh page,
  2. type number in both inputs and click on button -> result and unit gets saved.
  3. Now type different numbers in inputs and click on button -> and now the resultComment gets saved as well). Ignore weird calculation results. Its missing parts which I didn't add to StackBlitz.

component ts

 class HistoryResult {
  constructor(
    public result: number,
    public temperatureUnit: string,
    public resultComment?: string
  ) {}
}
  resultHistory: HistoryResult[] = []; 

//in ngOnInit iam initializing resultHistory so it stays on page when i refresh and adding comment to each result
ngOnInit() {
...
..code..
...
    this.resultHistory = JSON.parse(localStorage.getItem('result')) || [];
    this.resultHistory.map((item) => {
      item.resultComment = this.heatIndexService.determineComment(
        item.result,
        item.temperatureUnit
      );
    });
}
onCalculateButtonClick(): void {
    this.result = null;
    this.resultTemperatureUnit = this.temperatureUnit.value;
    if (this.heatIndexForm.invalid) {
      this.heatIndexForm.controls['temperature'].markAsDirty();
      this.heatIndexForm.controls['humidity'].markAsDirty();
      return;
    }
    this.result = this.heatIndexService.calculateHeatIndex(
      this.temperatureValue,
      this.humidityValue,
      this.resultTemperatureUnit.code
    );
    this.heatIndexService.saveResultInLocalStorage(
      this.result,
      this.temperatureUnit.value.code,
      this.resultHistory
    );
    this.resultHistory.map((item) => {
      item.resultComment = this.heatIndexService.determineComment(
        item.result,
        item.temperatureUnit
      );
    });
  }

service functions

  saveResultInLocalStorage(
    result: number,
    unit: string,
    historyResults: HistoryResult[]
  ): void {
    // Check if result is the same as last one
    if (
      historyResults.length === 0 ||
      historyResults.slice(-1)[0].result !== result
    ) {
      historyResults.push(new HistoryResult(result, unit));
      // Remove oldest result if more than 3 results
      if (historyResults.length > 3) {
        historyResults.shift();
      }
      localStorage.setItem('result', JSON.stringify(historyResults));
    }
  }

  determineComment(temperature: number, units: string): string {
    if (units === 'C') {
      temperature = (temperature * 9) / 5   32;
    }
    if (temperature >= 75 && temperature <= 90) {
      return 'Caution: fatigue is possible with prolonged exposure and activity. Continuing activity could result in heat cramps.';
    } else if (temperature > 90 && temperature <= 105) {
      return 'Extreme caution: heat cramps and heat exhaustion are possible. Continuing activity could result in heat stroke.';
    } else if (temperature > 105 && temperature <= 130) {
      return 'Danger: heat cramps and heat exhaustion are likely; heat stroke is probable with continued activity.';
    } else {
      return 'Extreme danger: heat stroke is imminent.';
    }
  }

and HTML where the previous calculations are shown

  <p-table [value]="resultHistory" [tableStyle]="{'min-width': '50rem'}">
      <ng-template pTemplate="header">
          <tr>
              <th>Heat Index</th>
              <th >Effect on the body</th>
          </tr>
      </ng-template>
      <ng-template pTemplate="body" let-history>
          <tr>
              <td>{{history.result | number : '1.2-2'}}&deg;{{history.temperatureUnit}}</td>
              <td>{{history.resultComment}}</td>
          </tr>
      </ng-template>
  </p-table>

CodePudding user response:

You are mutating the array when calling this.historyResults.map(...) and then saving that value in saveResultInLocalStorage when calling localStorage.setItem(historyResults).

Change your value to be saved as a new array with only the properties you want then call localStorage.setItem(newValue).

To pick out only the properties you want and save them you could do the following:

const resultsToSave: Pick<HistoryResult, 'result' | 'temperatureUnit'>[] = historyResults.map(h => ({ result: h.result, temperatureUnit: h.temperatureUnit }));
localStorage.setItem('result', JSON.stringify(resultsToSave));

An alternative to using Pick above to get the reduced type could be to use Omit which may be shorter depending on how many fields you specify, e.g.:

const resultsToSave: Omit<HistoryResult, 'resultComment'>[] = historyResults.map(h => ({ result: h.result, temperatureUnit: h.temperatureUnit }));
  • Related