robinvdvleuten / vuex-persistedstate

💾 Persist and rehydrate your Vuex state between page reloads.
https://npm.im/vuex-persistedstate
MIT License
5.77k stars 379 forks source link

argument str must be a string on nuxt server persist #398

Open iliapisaniy opened 3 years ago

iliapisaniy commented 3 years ago

What you did: Install package and use default plugin from readme (nuxt cookie server persist)

What happened: If no cookie set (example on first page loading).

if (process.server) {
     const parsedCookies = cookie.parse(req.headers.cookie);
     return parsedCookies[key];
}

throws type error argument str must be a string

Reproduction sandbox:

Problem description: cookie package receive string as first parameter but undefined given on empty cookie in browser

Suggested solution: Check is request.headers.cookie is string and set it to blank if not

VconexID commented 3 years ago

i have this issue as well in new version, currently i use vuex-persistedstate 3.1.0 and it works perfectly.

iliapisaniy commented 3 years ago

I fixed this issue by checking is request.headers.cookie is string like this

let headerCookie = req.headers.cookie;
if (typeof headerCookie !== 'string') {
  headerCookie = '';
}
const parsedCookies = cookie.parse(headerCookie);
return parsedCookies[key];
robinvdvleuten commented 3 years ago

This seem to be more like a Nuxt issue on how it handles incoming cookies.

iliapisaniy commented 3 years ago

I this it's problem of cookie package and it ca be resolved by fix readme plugin template (changes in related mr)

dosstx commented 3 years ago

@ilyapisany I still seem to get the argument str must be a string error.

I have added to Nuxt like so:

/plugins/persistedState.js:


import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
import cookie from 'cookie'

export default ({ store, req }) => {
  createPersistedState({
    storage: {
      getItem: (key) => {
        // See https://nuxtjs.org/guide/plugins/#using-process-flags
        if (process.server) {
          let cookieHeader = cookie.parse(req.headers.cookie)
          if (typeof cookieHeader !== 'string') {
            cookieHeader = ''
          }
          const parsedCookies = cookie.parse(cookieHeader)
          return parsedCookies[key]
        } else {
          return Cookies.get(key)
        }
      },
      // Please see https://github.com/js-cookie/js-cookie#json, on how to handle JSON.
      setItem: (key, value) =>
        Cookies.set(key, value, { expires: 365, secure: false }),
      removeItem: (key) => Cookies.remove(key)
    }
  })(store)
}

And plugins:

plugins: [
    { src: '~/plugins/persistedState.js' }
]

Any ideas?

mtzrmzia commented 3 years ago

same here.. has anyone can fixed it?

Jimmar commented 3 years ago

a one liner alternative that worked for me was

const parsedCookies = cookie.parse(req.headers.cookie ?? "");
return parsedCookies[key];

or the full the plugin

// plugins/persistedState.js

import createPersistedState from "vuex-persistedstate";
import Cookies from "js-cookie";
import cookie from "cookie";

export default ({ store, req }) => {
  createPersistedState({
    paths: [...],
    storage: {
      getItem: key => {
        if (process.server) {
          const parsedCookies = cookie.parse(req.headers.cookie ?? "");
          return parsedCookies[key];
        } else {
          return Cookies.get(key);
        }
      },
      setItem: (key, value) => Cookies.set(key, value, { expires: 1, secure: false }),
      removeItem: key => Cookies.remove(key)
    }
  })(store);
};