Arte
Arte

Reputation: 417

Getting items from localstorage returns null

I have a React app that loads items from a api call from a database, if there is no data in local storage. I will then set the state with data and load the data in local storage. Next time the app loads it will take the data from local storage instead. The data is mapped out in the return statement.

The Problem is it still returns null even when there is data in local storage.

I will load the data from componentDidMount:

The below code will run the function "loadItems" that first check if there is any data in localstorage (name "workItems") and if so, store it in the state. If it isn't, it will call the database in an api call, store the data to state and also store the data in localstorage which will be used next time the component mounts. I have confirmed that the data is stored in the browser. But when the data from the localstorage exist, is mapped to the state and finally mapped out in the return from the render function it will complain the data is "null". How come? The data is stored in the local storage and exist there when I inspect it from the dev tools.

componentDidMount() {
  this.loadItems(false);
}

async loadItems(forcedUpdate) {
  const payload = {
    forcedUpdate: forcedUpdate
  };
  if (localStorage.getItem('workItems').length > 0) {
    let data = localStorage.getItem("workItems");
    this.setState({
      workitems: localStorage.getItem("workItems"),
      loading: false,
      sources: allSources,
      showSources: allSources,
    }, () => {
      return;
    });
  }

  var apiUrl = "api/WorkItem/GetWorkItems";

  const response = await Axios.default.post(apiUrl, payload);
  console.log(response);
  var allSources = response.data.items
    .map(item => item.source)
    .filter((value, index, self) => self.indexOf(value) === index);

  this.setState({
    workitems: response.data.items,
    loading: false,
    sources: allSources,
    showSources: allSources,
    failedScrape: response.data.failedscrape,
    lastUpdated: response.data.lastUpdated
  });
  localStorage.setItem('workItems', response.data.items);

}

Upvotes: 2

Views: 10479

Answers (2)

tolotra
tolotra

Reputation: 3270

You can use this hook. Otherwise, to fetch data from local storage, use these functions:

const getValue = (key, defaultValue = {}) => {
  try {
    // read value from local storage
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : defaultValue;
  } catch (error) {
    console.log(error);
    return defaultValue;
  }
}

const setValue = (key, value) => {
  try {
    window.localStorage.setItem(key, JSON.stringify(value));
  } catch (error) {
    console.log(error);
  }
}

setValue("test", {test: "Test value"})
console.log(getValue("test"))

Upvotes: 1

Abdullah Danyal
Abdullah Danyal

Reputation: 1146

localStorage.setItem(key, value) expecting a value to be string. When you pass the object such as [{id: 1}], it will typecast it to string. Hence the object becomes the string like this "[object Object]".

localStorage.setItem('test', [{id: 1}]);
const item = localStorage.getItem('test');
console.log(item) // "[object Object]" a string
console.log(item[0]) // "["
console.log(item[1)) // "o"

Solution

The solution is to stringify it before saving to localStrage and parse it after getting the item.

localStorage.setItem('workItems', JSON.stringify(response.data.items));
// when you get the items
if (JSON.parse(localStorage.getItem('workItems')).length > 0)

Upvotes: 1

Related Questions