0

I am calling an API to fetch data and that is stored in an array. I have also appended a new object to each item in the array with a default boolean value of true. When I click on a specific element in the array that is rendered, the boolean value is changed to false and a new icon is rendered. I've used localstorage to preserve the state after a page refresh.

The problem I am having is that when I refresh the page, I want the API call to update the state of the array but I also want to preserve the state of the boolean value that is in my localstorage..

The part I am stuck on now is that I have a condition that checks for localstorage in my componentDidMount() method and if this is not true the entire state of the array is updated. Obviously if I remove this check the state of my boolean values will be reset to true..

import React from 'react';
import StarBorder from '@material-ui/icons/StarBorder';
import Star from '@material-ui/icons/Star';
import axios from 'axios';

class Test extends React.Component {
    constructor(props) {
        super(props);

        var newData = [];

        if (localStorage.getItem('new')) {
            newData =  JSON.parse(localStorage.getItem('new'));
        }

        this.state = {
          data: newData,
        }
    }

    componentDidMount() {

            axios.get('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=true')
            .then(res => {
                const data = res.data;

                if (!localStorage.getItem('new')) {
                    this.setState({ data: data.map(x => ({...x, starIcon: true}))})
                }
            }) 
    }

    handleClick = (i) => {
        this.setState(prevState => ({
          data: prevState.data.map((x, key) => (key === i ? {
            ...x,
            starIcon: !x.starIcon
          } : x))
        }), () => {
          localStorage.setItem('new', JSON.stringify(this.state.data));
        });
      }

    render() {
        return (
        <div>
            <table border="1">
                <thead>
                    <tr>
                    <td>Icon</td>
                    <td>Name</td>
                    <td>Price</td>
                    </tr>
                </thead>
                <tbody>
                {this.state.data.map((n, i) => {
                    return (
                        <tr>
                        <td> <span onClick={() => this.handleClick(i)}> {n.starIcon ? <StarBorder/> : <Star /> } </span> </td>
                        <td>{n.name}</td>
                        <td>{n.current_price}</td>
                        </tr>
                    );
                    })}
                </tbody>
            </table>
        </div>
        );
    }
}

export default Test;
2
  • If I understood correctly you want old items with their value (from localstorage) to be merged with new items (items loaded from the API which are not present already in the old ones)? Commented Aug 13, 2019 at 15:06
  • Yeah thats pretty much what I'm looking for here Commented Aug 13, 2019 at 15:14

1 Answer 1

1
const fromLocalStorage = localStorage.getItem('new');

if (localStorage.getItem('new')) {
  const dataFromLocalStorage = JSON.parse(fromLocalStorage);
  this.setState({ data: data.map((x, i) => ({...x, starIcon: dataFromLocalStorage[i].starIcon }) })
} else {
  this.setState({ data: data.map(x => ({...x, starIcon: true}))})
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.