Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior when parsing JSON cookie using cookie-react in React / NextJS

I have a cookie called '_user_attributes'. The cookie contains a URL encoded string of JSON data. For example,

%7B%22user_id%22%20%3A%20%2212345%22%2C%20%22user_givenName%22%20%3A%20%22First%22%20%7D

which decodes to

{"user_id" : "12345", "user_givenName" : "First" }

Basically, I want to turn the decoded cookie into an object. So I've been doing the following:

var _user_attributes = cookies.get('_user_attributes')
const user_attributes = JSON.parse(_user_attributes)

And that works. The strange thing though, is it only works the first time I load the page. If I refresh the page, I get 'SyntaxError: Unexpected token u in JSON at position 0'.

I am completely confused as to why this is the case. If anyone has any suggestions, I would really appreciate it. The full code of my page is below.

import React, { Component, createRef } from "react";
import { withCookies, Cookies } from "react-cookie";

class App extends Component {
  constructor(props) {
    super(props)
    const { cookies } = props;
    var _user_attributes = cookies.get('_user_attributes')
    const user_attributes = JSON.parse(_user_attributes)
    console.log(_user_attributes)
    this.state = {
      name: user_attributes.name
    }
  }
  render() {
    return (
      <p>{this.state.name}</p>
    );
  }
}

export default withCookies(App);
like image 641
mic Avatar asked Nov 07 '22 06:11

mic


1 Answers

You are encoding the JSON while storing in the cookie but while reading it back cookie value is directly fed to JSON.parse without decoding. Since the JSON parser is not able to parse the encoded value, it is throwing the error.

Here is the codesandbox for the working cookie retrieval - https://codesandbox.io/s/silly-shtern-2i4dc?file=/src/App.js

import React, { Component } from "react";
import { withCookies } from "react-cookie";

class Test extends Component {
  constructor(props) {
    super(props);
    const { cookies } = props;
    var _user_attributes = cookies.get("_user_attributes");
    if (_user_attributes) {
      _user_attributes = decodeURI(_user_attributes);
      const user_attributes = JSON.parse(_user_attributes);
      console.log(user_attributes);
      this.state = {
        name: user_attributes.user_givenName
      };
    }
    //if the cookie doesn't exist. added just for testing
    else {
      let temp = { user_id: "12345", user_givenName: "First" };
      temp = encodeURI(JSON.stringify(temp));
      cookies.set("_user_attributes", temp, { path: "/" });
    }
  }
  render() {
    return <p>{this.state?.name || "No Cookie yet"}</p>;
  }
}

export default withCookies(Test);

But I am not sure how you are able to access the cookie on First load without decoding.

I am able to consistently read the cookie after decoding and parsing on any load of the page. But without decoding I get error all the time.

like image 144
Arpitha Chandrashekara Avatar answered Nov 12 '22 19:11

Arpitha Chandrashekara