1

I'm trying to store an array of objects in local storage. I'm using this common method:

localStorage.setItem( 'products', JSON.stringify(this.state.products) );
let initialProducts = JSON.parse(localStorage.getItem("products") || "[]")

I'm getting the error:

SyntaxError: Unexpected token o in JSON at position 1

I know that error means I am parsing the JSON twice, however if I do not parse it, when I get "products" from localStorage it is:

[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

What am I doing wrong?

Full code:

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import ProductList from "../products/ProductList";
import productData from "../products/model";

class App extends Component {
  constructor(props) {
    super(props);
    let initialProducts = JSON.parse(localStorage.getItem("products") || "[]")
    console.log(initialProducts);
    this.state = {
      newProductName: "",
      newProductPrice: 0,
      products: initialProducts
    };
  }

  updateNewProductName = event => {
    this.setState({ newProductName: event.target.value });
  };

  updateNewProductPrice = event => {
    this.setState({ newProductPrice: event.target.value });
  };

  addProduct = () => {
    this.state.products.push({
      name: this.state.newProductName,
      price: this.state.newProductPrice
    });
    this.setState({
      products: this.state.products
    });
    localStorage.setItem( 'products', JSON.stringify(this.state.products) );
  };

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <div className="App-header-container">
            <img
              src="https://www.ezyvet.com/wp-content/uploads/2016/04/ezyVet-Logo-22-4.png"
              alt="ezyVet Cloud Veterinary Practice Management Software"
              id="logo"
              className="App-logo"
              data-height-percentage="65"
              data-actual-width="768"
              data-actual-height="252"
            />
          </div>
        </header>
        <div className="App-header-container">
          <ProductList products={this.state.products} />
          <input
            type="text"
            id="uname"
            name="uname"
            required
            minLength="2"
            placeholder="name"
            value={this.state.newProductName}
            onChange={this.updateNewProductName}
          />
          <input
            type="number"
            id="uprice"
            name="uprice"
            required
            placeholder="price"
            value={this.state.newProductPrice}
            onChange={this.updateNewProductPrice}
          />
          <button onClick={this.addProduct}>Add Product</button>
        </div>
      </div>
    );
  }
}

export default App;
9
  • Did you verify the raw string inside localstorage? Does it contain what you think it contains? Commented Aug 8, 2018 at 7:01
  • @NisargShah I just did and the value is [object Object],[object Object],[object Object],[object Object],[object Object],[object Object]. Strange because in the example solution at the top of my question it sets the localStorage in the same fashion. Commented Aug 8, 2018 at 7:07
  • if thethis.state.products is mistakenly passed to localStorage as localStorage.setItem('products',this.state.products) instead of localStorage.setItem('products',JSON.stringify(this.state.products)) then it will always be stored as [object Object] . Can you please check what is the value from JSON.stringify(this.state.products) before setting in localstorage? Commented Aug 8, 2018 at 7:16
  • @vikscool console.log(JSON.stringify(this.state.products)); gives [{"name":"Sledgehammer","price":125.75},{"name":"Axe","price":190.5},{"name":"Bandsaw","price":562.13},{"name":"Chisel","price":12.9},{"name":"Hacksaw","price":18.45},{"name":"eeee","price":"02"}] Commented Aug 8, 2018 at 7:18
  • @BeniaminoBaggins Try logging this.state.products before invoking localStorage.setItem. I am suspecting it is already a string at that stage, so JSON.stringify doesn't affect it. Commented Aug 8, 2018 at 7:21

1 Answer 1

1

It works when I double up on the JSON.parse and JSON.stringify.

For example:

let initialProducts = JSON.parse(JSON.parse(localStorage.getItem("products")));
localStorage.setItem( 'products', JSON.stringify(JSON.stringify(this.state.products) ));

Might be something to do with the objects being nested inside the array.

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.