Open arielnmz opened 5 years ago
Hmmm. I can't say why that's not working.
Can you post in the Nuxt issues and see what comes up?
I'm trying to replicate it with a clean, new nuxt app.
I've created a new nuxt app and set up a simple store with the following structure:
export const state = () => ({
ui: {
sub: {
attr: false,
...
},
},
})
And I'm trying to use it like this in my component
export default {
name: 'MyComponent',
computed: {
...sync('ui@sub.*')
}
}
And this is the error I get:
Unable to expand wildcard path 'ui@sub.*':
Changing it to ui@sub
makes it work again
It works in version 1.1.3
with nuxt@^1.4.5
, and updating to nuxt 2 breaks it. Updating to vuex-pathify@^1.2.0
doesn't help btw.
What could nuxt be doing that breaks this?
OK, if you share the nuxt project I'll load it up and take a look.
Is it related to this at all?
https://github.com/davestewart/vuex-pathify/pull/46
Apparently Nuxt 2.x was doing some weird things. I didn't check, just trusted the contributor.
Finally, I was able to look closer into this. There are tons of scenarios (nuxt in ssr mode, client mode, loading pathify as a client plugin, as aserver plugin, as a vuex plugin). I'll explain a simple and the most common case, assuming we are using nuxt@^2.5.0
in ssr (universal) mode, and pathify@^1.2.0
:
If I try to e.g. sync
a path like 'ui@sub.*'
, pathify tries to expand it via expandSync
and fails because vuex.store.state
is null
at that moment. The reason a path like ui@sub
doesn't fail is because pathify is not trying to expand it, instead it just calls getOne
, syncOne
, etc., which don't need the state to be initialized (they just map the path to the corresponding getter/setter). The problem with the resolver function is that it checks if the state is initialized at the moment of expanding the path, and since it is null
, it just returns ''
(an empty string), and in the next stage it tries to reduce it, triggering an exception because a string doesn't have the reduce
method:
TypeError: paths.reduce is not a function
/**
* Utility function to expand wildcard path for sync()
*
* @param {string} path wildcard path
* @param {object} state state hash
* @returns {array|string}
*/
function expandSync (path, state) {
if (!init(path, state)) {
return ''
}
return resolveStates(path, state)
}
Then:
/**
* Helper function to convert an array of paths to a hash
*
* Uses the last path segment as the key
*
* @param {string[]} paths An array of paths to convert to a hash
* @returns {object} A hash of paths
*/
function makePathsHash (paths) {
return paths.reduce(function (paths, path) {
var key = path.match(/\w+$/);
paths[key] = path;
return paths
}, {})
}
The first thing that comes to mind is to return []
instead of ''
, this prevents pathify from crashing but doesn't change the fact that the store wasn't initialized and therefore can't even expand the path.
TL;DR the problem is Nuxt trying to render the routes before initializing the store. Can somebody replicate a working scenario? In the meantime, the "solution" would be to avoid using wildcards.
Going a step further, this seems to happen only when pathify is used in a layout or any component in a layout
Bug report in nuxt's github https://github.com/nuxt/nuxt.js/issues/5405
Hey, thanks for investigating!
I know it's not fun when the codebase is not your own.
Out of interest (and I assume you used the source) how did you find navigating around the source?
Did it seem logical?
I actually just put some breakpoints in the bundled script to find what's it doing, but I'm seeing the source now, and yes, I can say it's pretty well organized, I quickly found my way around. Ty for your time
FYI, I found a really cool Chrome extension the other day called OctoLinker which adds live links to GitHub repos:
It's great for this kind of thing!
Looks great! Im going to give it a try, ty
2.6.1
wildcard error still here
Nuxt 2.6.1 ?
Yep
I assume this is because of core-js3, which is nuxt roll over after 2.4.5 (core-js2) release
Ah I see.
So you mean with the VP 1.2.2 update, Nuxt still has its errors.
You don't mean that Nuxt have released something, but it didn't fix it.
So you mean with the VP 1.2.2 update, Nuxt still has its errors.
Right : )
Even after reverting back to 2 version
Since core-js@2 and core-js@3 are both supported from babel 7.4.0, Starting from 2.6 Nuxt supports both versions (#5411). It is highly advised to stick with 2 (default) unless having a special dependency that needs 3. (Instructions for core-js@2 are not required but recommended) https://github.com/nuxt/nuxt.js/releases
it doesn't work ~_~
I see this issue with just a vanilla vue-cli
app when I attempt to use wildcard expansion—no Nuxt, not even vue-router. See this sample repo:
https://github.com/yowzadave/vuex-pathify-test
in the "HelloWorld.vue" component (https://github.com/yowzadave/vuex-pathify-test/blob/master/src/components/HelloWorld.vue), the wildcard get
fails with the above error. The non-wildcard get
(commented out here) works fine.
I believe I'm having a related issue.
The error happens if I import my router into a module file in any way. I suppose it's because the store theoretically isn't initialised in this file, it's just a file that exports one of the modules of the state. I don't (yet) do anything with the router... Just importing it causes the error.
Is there any way to get it to work?
My current workaround is to do the things in components that I would rather do in actions.
Thanks.
Hi @VesterDe,
This is probably an order-of-import issue.
As soon as you import your router file, webpack will then try to import everything that is included in that file, so you end up with a race condition because suddenly your components are being imported before the store they depend on.
You'll have to think of a way to allow the store to finish its setup before using the router, or at least the routes and the dependent components it depends on. Consider adding routes dynamically, lazy-loading of routes or something like this:
// helper
function router () {
return require('/router').default
}
// use router in an action
const actions {
doSomething () {
router().whatever()
}
}
Let me know how you get on :)
Thanks for the feedback, it seemed like what you describe to me too.
I've now solved it the way you recommended, although I'm not crazy about how it looks...
I do prefer to handle the redirect inside actions though, so I'll keep it.
For anyone wondering how exactly it looks for me, it's:
const loadRouter = () => {
return require("@plugins/router").default
};
// Inside my login action
let router = loadRouter();
if(router.app._route.query.loginRedirect){
router.push(router.app._route.query.loginRedirect);
}
Another option would be moving all that code to a helper in the router folder, then you only need do:
import { isLoggingIn } from '@plugins/router'
const actions = {
login () {
if(!isLoggingIn()) {
// your code
}
}
}
Because isLoggingIn()
(or whatever you want to call it) is itself a function, it won't reference the router until you use it, so won't suffer the same order-of-import issues you were previously.
Also, if you are doing everything with the URL, there's nothing to stop you parsing the URL directly with location.search
After upgrading a working project from nuxt 1.4 to 2.5 I'm getting this error
This is how I added pathify to the vuex plugins:
I'm using nuxt in spa mode