Git Product home page Git Product logo

Comments (21)

maple3142 avatar maple3142 commented on June 15, 2024

Could you show what doesn't working?
In this fiddle, vuex modules state is persisted as my expectation.

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

The state is persisted but in the components and in the getters returns undefined.
it has begun since i separated into modules, than since i couldn't find the error i started to simplify the store.
Now It works as expected if i comment the plugin

I believe it has something to do with typescript

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

In addiction, some of the state values work as expected (username for example), loginError instead does not work

loggrdIn is accessible but non persisted, I have not idea of what is going on

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

Try updating to version 2.3.3, it should work now.

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

Still doesn't work in my case.

I have updated to 2.3.3, cleared old storage but nothing change

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

I finally realized that how did that happen...
It is because internal merge function is a shallow clone function like Objec.assign.
It should be solved if you pass a deep clone function to merge option, like _.cloneDeep.

But there is room for discussion about should this module include deep clone function inside or not.
I implement those thing instead of importing npm modules is order to reduce the bundle size.

This is how internal merge function works.

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

I had written a function for the deep cloning.

function cloneObject(obj1 :any, ...objs :any[]) {
 
  for (const obj2 of objs) {
    if (obj2 === null || typeof obj2 !== "object") {
      return obj2;
    }
    // give temporary-storage the original obj's constructor
    obj1 = obj2.constructor();
    for (const key in obj2) {
      obj1[key] = cloneObject(obj1[key], obj2[key]); //here i tried passing this instead of obj1[key] but ts denied me
    }
  }
  return obj1;
}

Now everything is broken so i believe that your previous comment is the right way but i have no clue how to implement it

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

Example: https://jsfiddle.net/maple3142/drgzj1h3/

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

store.ts

import Vue from "vue";
import Vuex from "vuex";

import storage from "vuejs-storage";

import auth from "./modules/auth";
import navigation from "./modules/navigation";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    auth,
    navigation
  },
  state: {
    isAppLoading: false
  },
  mutations: {
    changeAppLoadingState(state: any, appLoadingState) {
      state.isAppLoading = appLoadingState;
    }
  },

  actions: {},

  plugins: [
    storage({
      namespace: "test_session",
      storage: window.sessionStorage,
      keys: [
        "auth.loggedIn",
        "navigation.breadcrumb",
        "navigation.currentPosition"
      ],
      merge: _.cloneDeep
    }),
    storage({
      namespace: "test_local",
      keys: ["auth.username"],
      merge: _.cloneDeep
    })
  ]
});

It says that it cannot find name _.
I believe it is due to typescript, any thoughts?

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

Symbol _ usually means lodash (a popular js library).
So you need to import _ from 'lodash', and npm i lodash -S.

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

Besides, if you want a simple merging function instead a big library.
You can use this(not fully tested)

const isobj=x=>typeof x==='object'&&!Array.isArray(x)&&x!==null
const merge=(obj1,...objs)=>{
	for(const obj2 of objs){
  	for(const k in obj2){
    	if(!obj2.hasOwnProperty(k))continue
      if(isobj(obj2[k]))merge(obj1[k],obj2[k])
      else obj1[k]=obj2[k]
    }
  }
  return obj1
}

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

I know and i had imported it, i was missing
npm install @types/lodash --save-dev
for typescript.

It seems to work with lodash i could try this script if you want and report if it does the job

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

@AndreaMinato You can use v2.4.0 now, which include deep merging function inside.

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

Updated to version 2.4.0, removed lodash, cleared storage, session and all other site data.

It all works until i have an object inside my vuex state

Error Log

vuejs-storage.min.js?6da9:1 Uncaught TypeError: Cannot set property 'id' of null
    at o (vuejs-storage.min.js?6da9:1)
    at o (vuejs-storage.min.js?6da9:1)
    at o (vuejs-storage.min.js?6da9:1)
    at eval (vuejs-storage.min.js?6da9:1)
    at eval (vuex.esm.js?358c:351)
    at Array.forEach (<anonymous>)
    at new Store (vuex.esm.js?358c:351)
    at eval (store.ts?57f0:13)
    at Object../src/store/store.ts (app.js:1464)
    at __webpack_require__ (app.js:679)

Session storage (same for local but it has only a string so it works)

image

store.ts

import Vue from "vue";
import Vuex from "vuex";

import storage from "vuejs-storage";

import auth from "./modules/auth";
import navigation from "./modules/navigation";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    auth,
    navigation
  },
  state: {
    isAppLoading: false
  },
  mutations: {
    changeAppLoadingState(state: any, appLoadingState) {
      state.isAppLoading = appLoadingState;
    }
  },

  actions: {},

  plugins: [
    storage({
      namespace: "test_session",
      storage: window.sessionStorage,
      keys: [
        "auth.loggedIn",
        "navigation.breadcrumb",
        "navigation.currentPosition"
      ],
    }),
    storage({
      namespace: "test_local",
      keys: ["auth.username"],
    })
  ]
});

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

Can you import vuejs-storage/dist/vuejs-storage.js version for better error message?

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024
vuejs-storage.js?3783:68 Uncaught TypeError: Cannot set property 'id' of null
    at merge (vuejs-storage.js?3783:68)
    at merge (vuejs-storage.js?3783:66)
    at merge (vuejs-storage.js?3783:66)
    at eval (vuejs-storage.js?3783:146)
    at eval (vuex.esm.js?358c:351)
    at Array.forEach (<anonymous>)
    at new Store (vuex.esm.js?358c:351)
    at eval (store.ts?57f0:13)
    at Object../src/store/store.ts (app.js:1464)
    at __webpack_require__ (app.js:679)


merge | @ | vuejs-storage.js?3783:68
-- | -- | --
  | merge | @ | vuejs-storage.js?3783:66
  | merge | @ | vuejs-storage.js?3783:66
  | (anonymous) | @ | vuejs-storage.js?3783:146
  | (anonymous) | @ | vuex.esm.js?358c:351
  | Store | @ | vuex.esm.js?358c:351
  | (anonymous) | @ | store.ts?57f0:13
  | ./src/store/store.ts | @ | app.js:1464
  | __webpack_require__ | @ | app.js:679
  | fn | @ | app.js:89
  | (anonymous) | @ | router.ts?dbe3:1
  | ./src/router.ts | @ | app.js:1440
  | __webpack_require__ | @ | app.js:679
  | fn | @ | app.js:89
  | (anonymous) | @ | main.ts?c77e:1
  | ./src/main.ts | @ | app.js:1424
  | __webpack_require__ | @ | app.js:679
  | fn | @ | app.js:89
  | 0 | @ | app.js:1503
  | __webpack_require__ | @ | app.js:679
  | (anonymous) | @ | app.js:725
  | (anonymous) | @ | app.js:728

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

I think it is a issue about merge, but I cannot reproduce it.
I added some test in 8ea21f6, but all tests still passed, did I miss anything?

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

I don't know maybe something like this should be more similar to my case:

// your code
  modules: {
    test: {
      state: {
        ar: [{ value: 1 }, { value: 2 }],
        wontBeSave: 1,
        customObject: {
          propA: "some sort of string here",
          propB: "another string here"
        }
      }
    }
  }
//your code

from vuejs-storage.

AndreaMinato avatar AndreaMinato commented on June 15, 2024

@maple3142 So i have cloned your repo to dive deeper into the code and I saw that the test check if the selected storage is saved in the right way.

The storage is correct but in some way i believe it fails when vuex read from it.

So i put a breakpoint in the merge function and i found what was wrong.

navigationModule.ts

const navigationModule: Module<any, any> = {
  state: {
    currentPosition: null, //Here i must use {}
    breadcrumb: []
  },
  getters: {},
  mutations: {  },
  actions: {}
};

in the merge after some iteration vuejs-storage try to put into my state.navigation.currentPosition[prop] what is stored in the session under storage.navigation.currentPosition[prop], but currentPosition in the state is null due to my declaration. so I changed de default value of the object to {} instead of null.

now it seems to work

from vuejs-storage.

maple3142 avatar maple3142 commented on June 15, 2024

I think this problem is solved now, but I will add this issue to docs to prevent someone from encountering same problem.

from vuejs-storage.

ngekoding avatar ngekoding commented on June 15, 2024

I got the same problem because using null for the value, change to {} make it works. But I think the null value is better, any idea?

from vuejs-storage.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.