leveraging the localStorage feature in a for-in iteration

I am new to stackOverflow, although I have browsed the forums for help in the past. However, this time I couldn't find a solution to my current issue, so I decided to create an account and seek assistance.

The problem at hand is related to a workout application that consists of 3 pages - page 1: where the user selects gym equipment (bike, rower or x trainer) and difficulty level, page 2: displays specific workouts based on the selections, and page 3: the actual workout to be completed.

My goal is to store certain data in a localStorage object depending on the link clicked by the user. But, each time a link is clicked, only the last value in the 'for in' loop gets stored, regardless of the link. Here's a simplified explanation:

PAGE 1: User selects equipment and difficulty from dropdown menus

// Constructor function to create workout instances
function Workout(name, desc, loc, work_rest, res, intensity){
    // ... properties defined here
}

// Create Workouts for bike
var bike = {
    easy: [
        {workout_1: new Workout('Tabata', 'This is a tabata style workout', '../Workout_page_example/index.html', [20, 10,...])},
        {workout_2: new Workout('Classic_HIIT', 'This is a HIIT session', '../Workout_page_example/index.html',[60,30,...])},
        {workout_3: new Workout('Clock_Face', 'Beat the clock', '../Workout_page_example/index.html',[120, 60...])}
    ],
    int:[],
    adv:[]
};

btn.addEventListener('click', function() {
    if(equipment.value === "bike"){
        if(difficulty.value === "easy"){
            localStorage.setItem('get_info', JSON.stringify(bike.easy));
        } else if(difficulty.value === "int"){
            localStorage.setItem('get_info', JSON.stringify(bike.int));
        } else if(difficulty.value === "adv"){
            localStorage.setItem('get_info', JSON.stringify(bike.adv));
        }
        location.href = 'workouts/index.html';
});

This above page is working fine. Now, moving on to Page 2 which displays all available workouts based on the user's previous selections:

PAGE 2: Display workouts based on equipment and difficulty selected

window.addEventListener('load', function(){
    var getInfo = JSON.parse(localStorage.getItem('get_info'));
    var dom = document.getElementById('section');

    for(var key in getInfo){
        var obj = getInfo[key];
        
        for(var prop in obj){
            // display workout details
            dom.innerHTML += "<hr/><div class='workout_title'><h1>"+obj[prop].name.replace('_',' ')+"</h1></div>";
            dom.innerHTML += "<div class='workout_desc'><h4>"+obj[prop].desc+"</h4></div>";

            // store data in localStorage
            localStorage.setItem('work_rest', JSON.stringify(obj[prop].work_rest));
            localStorage.setItem('resistance', JSON.stringify(obj[prop].res));
            localStorage.setItem('intensity', JSON.stringify(obj[prop].intensity));

            dom.innerHTML += "<div class='workout_link'><a href='"+ obj[prop].loc +"' id='"+obj[prop].name+"'>START >></a></div>";
        }

    }

})

On clicking the links, only the data for the 'Clock Face' instance is being stored in the localStorage object. I understand why this is happening but unsure how to fix it.

Answer №1

There is a flaw in your current approach where you are cycling through the 3 workouts and saving them without giving the user a chance to choose a workout. This causes the stored workout data to be constantly overwritten in each iteration, resulting in only the final workout being saved in the array. This means that all previous workouts have been replaced, creating a chain of overwriting that leads to only one workout being stored effectively.

Answer №2

I managed to solve the issue:

 window.addEventListener('load', function(){

    var getInfo = JSON.parse(localStorage.getItem('get_info'));
    var dom = document.getElementById('section');

    var names=[]; //initialize names array
    var workRestArr = [];
    var resArr = [];
    var intArr = [];


    for(var key in getInfo){
        var obj = getInfo[key];


        for(var prop in obj){

            dom.innerHTML += "<hr/><div class ='workout_title'> <h1>"+obj[prop].name.replace('_',' ')+"</h1></div>"; //replace underscore with space in workout names with more than one word - display name
            dom.innerHTML += "<div class='workout_desc'><h4>"+obj[prop].desc+"</h4></div>"; //display description

            dom.innerHTML += "<div class='workout_link'><a id='"+obj[prop].name+"'>START >></a></div>";


            names.push(obj[prop].name); //store all ids in names array
            workRestArr.push(obj[prop].work_rest); //store all work_rest in array
            resArr.push(obj[prop].res); // store all resistance levels in array
            intArr.push(obj[prop].intensity); //store all intensity levels in an array

        }

    }


    for(var i = 0; i<names.length; i++){
        var el = document.getElementById(names[i]);
        var w = workRestArr[i];
        var r = resArr[i];
        var int = intArr[i];

        (function(w, r, int) {
            el.addEventListener('click', function() {
                localStorage.setItem('work_rest', JSON.stringify(w));
                localStorage.setItem('resistance', JSON.stringify(r));
                localStorage.setItem('intensity', JSON.stringify(int));
                location.href = '../Workout_Page_example/index.html';
            })
        })(w, r, int);

    }

})

Although I am still unsure of the intricate workings of this code, my assumption is that it involves closures and variable scope. It would be beneficial to have a detailed explanation. Thank you

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

What could be causing my update function to not run when I refresh the page?

As a non-developer trying to learn react.js, I am working on a section of my website that needs to update every few seconds with new content like a photo, header, and body text. I've encountered an issue where the data refreshes correctly after the p ...

renewing a div element without the need to reload the entire webpage

I'm currently developing a setup process for configuring a database. My goal is to allow the user to progress through each phase without having to refresh the page. However, I've encountered an issue while trying to implement the .load() function ...

The node-vibrant module in combination with React

Hey there, I'm currently attempting to display the hex color of a react Component using node-vibrant. (The node package is already installed) It works perfectly when executed with node from the console. |- file.js |- image.jpg file.js // I am havi ...

The beforeRouteUpdate hook in vue-router is unable to access the `this` keyword

I am currently creating a Vue.js application with vue-router. According to the documentation, within the hook beforeRouteUpdate, I have full access to the component using the keyword this: The documentation mentions that beforeRouteEnter is the only gu ...

What is the best way to include a new property to an existing interface and then export the updated interface in Typescript?

Can you provide guidance on creating a new interface - UIInterface that combines SummaryInterface with additional properties? For example: import { SummaryInterface } from 'x-api'; // summaryInterface includes 20+ predefined properties generated ...

The functionality of Vue is acting up with the HTML, unexpectedly refreshing when a button is clicked

I am currently experiencing an issue with my Vue application. When I click the button, it clears the input field (which it shouldn't) and doesn't perform any other actions. The variables "codigo" and "payload" do not display anything on the scree ...

Asynchronous task within an if statement

After pressing a button, it triggers the check function, which then executes the isReady() function to perform operations and determine its truth value. During the evaluation process, the isReady() method may actually return false, yet display "Success" i ...

What is the method for obtaining the div ID's from this form?

This is the scenario I am working on: my app takes the text inputted by the user and exports it to a specific website that contains similar elements. For example, if the user enters a title in the app and clicks a button, the app will transfer that value t ...

Ways to resolve the issue of BrowserWindow not being recognized as a constructor when trying to create a child window within the Electron

Currently, I am utilizing electron to construct an application with two windows. In my attempt to open a second window from the renderer process, I have implemented the following code snippet: const electron = require('electron'); const BrowserW ...

Execute JavaScript code once all the AngularJS template directives are fully loaded

On my HTML page, I am utilizing AngularJS template directives. Here is an example of how it looks: <div class="row"> <div class="col-sm-12"> <div logo></div> <div login-card></div> ...

Testing components in React Native using asynchronous Jest methods

I have a component that triggers a fetch request when it mounts and then displays the results. I've been struggling to create a test snapshot of this component after the request is completed. I've searched on various forums like SO but haven&apo ...

Sending an HTTP post request with form data and various field controls will not be directed to a Java backend

Recently, I've started working with AngularJs and I'm facing an issue with uploading image files along with their labels through a Jax-RS post rest API. My problem is that the control in my AngularJS controller is not entering the Java post API. ...

Can you explain the error message "a.split is not a function" in an Angular context?

My Angular application is encountering an error upon page load. The error message displayed is as follows: angular-amin.js:122 TypeError: a.split is not a function at r (angular-amin.js:186) at m.$digest (angular-amin.js:145) at m.$apply (angular-ami ...

When additional elements follow, the button ceases to function properly in JavaScript

I am working on creating a text-based idle game that involves multiple buttons and text around them. However, I have encountered an issue where the functionality stops working when I try to add text after the "Work" button. The callback function is no lon ...

Assessing personalized directive attributes

I am currently working on a custom directive that will activate a specified event when a particular expression evaluates as true. The code below demonstrates how it can be achieved when binding a single value- <div ng-trigger="value.someBoolean" /> ...

The challenge of navigating through $scope

In my Angular view/form, I have an input file element that is being utilized with ng-upload. The code snippet looks like this: <input id="img" type="file" name="image" onchange="angular.element(this).scope().setFile(this)"> <input id="imgname" ty ...

What could be causing my images not to show up when I use string interpolation for src links in Vue.js?

I've encountered an issue while working on Vue.js where I'm struggling to render a couple of images from the local directory. What puzzles me is that this problem arises when using string interpolation, like in the code snippet below: <img :s ...

The save feature becomes dysfunctional after switching to the Material-UI dependency in a React project

After integrating the Material-UI dependency into my ReactJS code, I encountered an issue where the "save" functionality no longer works properly. Previously, when editing a task in my simple Todo list app, the new name would be saved successfully. However ...

What is the best way to pass an array of 8-digit strings from an input in Angular to a Node.js backend?

I am currently facing a challenge where I need to pass an array of 8 digit strings from an Angular input to a Node.js endpoint. The method below works perfectly fine when passing a single string, but how can I handle an array of 8 digit strings as input? ...

Unattaching Events in AngularJS

I'm still navigating my way through the realms of Angular and MVC programming, uncertain if I'm on the right track. There's a jQuery snippet that I wish to implement in some of my partials, but not all. With event listeners that persist eve ...