Search code examples
arraysangulartypescriptlocal-storagelogic

Can not save the array in the local storage


Context: I wanted to create a "Favourites List" system to add heart-ed categories to the home page.I tried searching on google for a logic flow for this idea, but it was not helpful. So firstly, I made a logic where the clicked heart button checks the FavList array wether it contains the same section or not (the array accepts one section for now as a prototype), the heart buttons work fine but when the page is refreshed, the FavList becomes empty.

Example for vegetables section (food.component.html):

<div class="row">
            <div class="col-10">
                <h3 class="mb-3 d-inline">Vegetables
                    <button class="btn" (click)="addFavVeg()">
                        <i class="bi align-items-center border-0 text-danger" [ngClass]="favList.includes('vegetables') ? 'bi-heart-fill':'bi-heart'" id="vegetables"></i>
                    </button>
                </h3>
            </div>

food.component.ts:

export class FoodComponent implements OnInit {

  foodList: Product[]
  favList: string[] = this.productsService.favList

  addFavVeg() {
    this.productsService.addFavVeg()
  }

  addFavFruits() {
    this.productsService.addFavFruits()
  }

  constructor(private productsService: ProductsService) {}

  ngOnInit() {
    this.productsService.saveData('favList', JSON.stringify(this.favList))
    this.productsService.getData('favList')
    console.log(this.productsService.getData('favList'))
    return this.productsService.findAllFood().subscribe(data => {
      this.foodList = data
    })
  }

}

I decided to move the function the service where I have the localstorage functions.

products.service.ts:

export class ProductsService {

  favList: string[] = []

  addFavVeg() {
    if (this.favList.includes('vegetables')) {
      this.favList.pop();
    }
    else if (this.favList.length > 0){
      this.favList.pop();
      this.favList.push('vegetables');
    }
    else {
      this.favList.push('vegetables');
    }
    this.saveData('favList', this.favList)
    console.log(this.getData('favList'))
  }

  addFavFruits() {
    if (this.favList.includes('fruits')) {
      this.favList.pop();
    }
    else if (this.favList.length > 0){
      this.favList.pop();
      this.favList.push('fruits');
    }
    else {
      this.favList.push('fruits');
    }
    this.saveData('favList', this.favList)
    console.log(this.getData('favList'))
  }

  public saveData(key, value) {
    localStorage.setItem(key, value)
  }

  public getData(key) {
    JSON.parse(localStorage.getItem(key))
    console.log(JSON.parse(localStorage.getItem(key)))
  }
}

After that I checked the browser, the heart buttons still work fine, but the console throws an error preventing the localstorage to save the added values to the array: the error

I tried searching more about localstorage usages, but still can not integrate it with my favList idea. Any ideas?

I tried saving favList array in localstorage, I expected a message in the console with the array having the 'vegetables' or 'fruits' value, but I the result was an error with JSON.


Solution

  • At first, I changed the [ngClass] old expression to a function

    food.component.html:

    <div class="row">
                <div class="col-10">
                    <h3 class="mb-3 d-inline">Vegetables
                        <button class="btn" (click)="addFavVeg()">
                            <i class="bi align-items-center border-0 text-danger" [ngClass]="isVegs() ? 'bi-heart-fill':'bi-heart'" id="vegetables"></i>
                        </button>
                    </h3>
                </div>

    I did that to avoid any problems with getting data from the service to the component as a precaution. After that, I made favList = this.getData("favList") so that it gets updated everytime I click a button.

    Here is a the code for further understanding..

    food.component.ts:

      addFavVeg() {
        this.productsService.addFavVeg()
      }
    
      addFavFruits() {
        this.productsService.addFavFruits()
      }
    
      isVegs() {
        return this.productsService.isVegs()
      }
    
      isFruits() {
        return this.productsService.isFruits()
      }
    
      constructor(private productsService: ProductsService) {}

    Now all the logic is correctly added in the products.service.ts:

    favList: string[] = this.getData("favList")
    
      addFavVeg() {
        if (this.favList.includes("vegetables")) {
          this.favList.pop();
        }
        else if (this.favList.length > 0){
          this.favList.pop();
          this.favList.push("vegetables");
        }
        else {
          this.favList.push("vegetables");
        }
        this.saveData("favList", this.favList)
      }
    
      addFavFruits() {
        if (this.favList.includes("fruits")) {
          this.favList.pop();
        }
        else if (this.favList.length > 0){
          this.favList.pop();
          this.favList.push("fruits");
        }
        else {
          this.favList.push("fruits");
        }
        this.saveData("favList", this.favList)
      }
    
      isVegs(): boolean {
        return this.favList.includes('vegetables')
      }
    
      isFruits(): boolean {
        return this.favList.includes('fruits')
      }
    
      public saveData(key: string, value: string[]) {
        localStorage.setItem(key, JSON.stringify(value))
      }
    
       // changed string to string[]
       public getData(key): string[] | null {
        const data = localStorage.getItem(key);
        // console.log(data != null ? JSON.parse(data): "not found");
        return data != null ? JSON.parse(data) : null;
      }