universal-router
universal-router copied to clipboard
TypeError: Cannot read property 'substr' of undefined
I just updated all of my dependencies and now I am getting this error.
Server boots up just fine. However when I try to load the page this error occurs:
After calling src/server.js at line 147:1 it seems to be passing in an undefined route path or something is glitching. How is that so? Clearly my paths are defined as shown in this post.
Inside server.js. Line 147:1 is the line starting with: const route = await router.resolve
const context = {
// Enables critical path CSS rendering
// https://github.com/kriasoft/isomorphic-style-loader
insertCss: (...styles) => {
// eslint-disable-next-line no-underscore-dangle
styles.forEach(style => css.add(style._getCss()));
},
fetch,
// You can access redux through react-redux connect
store,
storeSubscription: null,
};
const route = await router.resolve({
...context,
path: req.path,
query: req.query,
});
if (route.redirect) {
res.redirect(route.status || 302, route.redirect);
return;
}
And here is the class func in universal-router (copied straightly from node_modules) that cannot proceed because it is catching an undefined value route:
class UniversalRouter {
constructor(routes, options = {}) {
if (Object(routes) !== routes) {
throw new TypeError('Invalid routes');
}
this.baseUrl = options.baseUrl || '';
this.resolveRoute = options.resolveRoute || resolveRoute;
this.context = Object.assign({ router: this }, options.context);
this.root = Array.isArray(routes) ? { path: '', children: routes, parent: null } : routes;
this.root.parent = null;
}
resolve(pathnameOrContext) {
const context = Object.assign(
{},
this.context,
typeof pathnameOrContext === 'string' ? { pathname: pathnameOrContext } : pathnameOrContext,
);
const match = matchRoute(
this.root,
this.baseUrl,
context.pathname.substr(this.baseUrl.length),
[],
null,
);
const resolve = this.resolveRoute;
let matches = null;
let nextMatches = null;
function next(resume, parent = matches.value.route) {
matches = nextMatches || match.next();
nextMatches = null;
if (!resume) {
if (matches.done || !isChildRoute(parent, matches.value.route)) {
nextMatches = matches;
return Promise.resolve(null);
}
}
if (matches.done) {
return Promise.reject(Object.assign(
new Error('Page not found'),
{ context, status: 404, statusCode: 404 },
));
}
return Promise.resolve(resolve(
Object.assign({}, context, matches.value),
matches.value.params,
)).then((result) => {
if (result !== null && result !== undefined) {
return result;
}
return next(resume, parent);
});
}
context.next = next;
return next(true, this.root);
}
}
So, in node_modules/src/UniversalRouter.js, how is it catching an undefined value when it is being executed after the context declaration?
resolve(pathnameOrContext) {
const context = Object.assign(
{},
this.context,
typeof pathnameOrContext === 'string' ? { pathname: pathnameOrContext } : pathnameOrContext,
);
const match = matchRoute(
this.root,
this.baseUrl,
context.pathname.substr(this.baseUrl.length),
[],
null,
);
Here are my routes.js:
const routes = {
path: '/',
// Keep in mind, routes are evaluated in order
children: [
{
path: '/',
load: () => import(/* webpackChunkName: 'home' */ './home'),
},
{
path: '/contact',
load: () => import(/* webpackChunkName: 'contact' */ './contact'),
},
/*{
path: '/login',
load: () => import('./login'),
},
{
path: '/register',
load: () => import('./register'),
},
*/{
path: '/about',
load: () => import(/* webpackChunkName: 'about' */ './about'),
},
/*{
path: '/privacy',
load: () => import('./privacy'),
},
{
path: '/admin',
load: () => import('./admin'),
},*/
{
path: '/rnews',
load: () => import('./rnews'),
},
{
path: '/cp',
load: () => import('./cp'),
},
// Wildcard routes, e.g. { path: '*', ... } (must go last)
{
path: '*',
load: () => import(/* webpackChunkName: 'not-found' */ './not-found'),
},
],
async action({ next }) {
console.log(next);
// Execute each child route until one of them return the result
const route = await next();
// Provide default values for title, description etc.
route.title = `${route.title || 'ForbiddenGrounds'}`;
route.description = route.description || '';
return route;
},
};
// The error page is available by permanent url for development mode
if (__DEV__) {
routes.children.unshift({
path: '/error',
action: require('./error').default,
});
}
export default routes;
Please see Migration from v3 to v4 section in changelog.
Also, changes from this PR can be useful to you: https://github.com/kriasoft/react-starter-kit/pull/1403