Redux not work inside in NEXT JS middleware - redux

How to use Redux inside NEXTJS middleware?
Any suggestion to achieve this problem, I try my useSelector in my index it's works fine but in middleware I don't know how to use it I'm newbie in nextjs.
//middleware.js
import { NextResponse } from 'next/server';
import { useSelector } from "react-redux";
import { store} from './store/store';
export function middleware(request) {
const auth = store.getState().user;
if (request.nextUrl.pathname.startsWith('/login')) {
if(auth ){
return NextResponse.rewrite(new URL('/' , request.url))
}
}
if (request.nextUrl.pathname.startsWith('/dashboard')) {
// This logic is only applied to /dashboard
}
}

It seems like reducers are not meant to be changed server side. I read a very similar issue here https://github.com/reduxjs/redux/issues/1745 Give it a try. Hope its helpful.

Related

next-connect TypeError: handlers[(i++)] is not a function

I am trying to implement route->middleware->endpoint api approach in Next.js using 'next-connect' library. Everything was working fine until I added .post() endpoint to the next-connect insance.
// pages/api/index
import { protect, restrictTo, createUser } from 'api-lib/controllers/authController'
import { getAllUsers } from 'api-lib/controllers/userController'
import all from 'api-lib/middlewares/all';
const route = all() // next-connect instance with options privided
route.use(protect) // rotect the route
.use(restrictTo('admin')) // restrict the route to admin
.get(getAllUsers)
export default route;
then I added .post() endpoint
route.use(protect) // rotect the route
.use(restrictTo('admin')) // restrict the route to admin
.get(getAllUsers) // ---- works fine until here
.post(createUser) // !!! got error
and got this error TypeError: handlers[(i++)] is not a function.
The createUser function worked correctly when I tested it in another route.
Any suggestions? Could it be a 'next-connect' bug?
I found the issue. Actually I was importing createUser from a wrong file by mistake.
changed
// pages/api/index
import { protect, restrictTo, createUser } from 'api-lib/controllers/authController'
import { getAllUsers } from 'api-lib/controllers/userController'
to
// pages/api/index
import { protect, restrictTo } from 'api-lib/controllers/authController'
import { getAllUsers, createUser } from 'api-lib/controllers/userController'

Adding prefix to Nextjs dynamic route

I have quite a lot of routes defined and one of the routes is dedicated to user profiles.
Each user has a public profile accessible from HTTP://example.com/#username.
I have tried creating file pages/#[username].js but it doesn't seem to work.
Is there a way to have this behavior without passing # sign with the username because this would greatly complicate index.js handling homepage and I would like to have that code separated.
You can now do this like so in next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/#:username',
destination: '/users/:username'
}
]
}
}
This will make any link to /#username go to the /users/[username] file, even though the address bar will show /#username.
Then, in your /pages/[username].tsx file:
import { useRouter } from 'next/router'
export default function UserPage() {
const { query = {} } = useRouter()
return <div>User name is {query.username || 'missing'}</div>
}
Next.js does not support this yet.
You should watch this issue.

How to redirect to a external page?

So, I need to redirect to a external page when my site return 400. I've tried follow the Next.js redirect tutorial, didn't work, and I've tried with window.locate, but breaks my site in production.
Here's the code I've tried:
import React from 'react'
import Router from 'next/router'
export default class extends React.Component {
static async getInitialProps({ res }) {
if (res) {
res.writeHead(302, {
Location: 'http://google.com'
})
res.end()
} else {
Router.push('/')
}
return {}
}
}
Is there another solution without the window.locate method?
Thank you!
indeed that is the bad side from next.js the routing is not working well.
i get the same issue before than i change it back to reactjs
kind regards

Call sub-reducer in default block of a parent reducer

Is it ok to have a reducer calling sub-reducers in its default block?
function aReducer(state = {}, action) {
switch(action.type) {
case XYZ:
... // know what to do
default:
// don't know this action, let's delegate to the children
return {
sub1: subReducer1(state.sub1, action),
sub2: subReducer2(state.sub2, action)
}
}
}
Yes, that's absolutely legal and reasonable to do.
You might want to read through the Redux docs section on "Structuring Reducers" for further ideas on how you can organize reducer logic as well.
You can put all the reducers in a common folder and inside that, you can combine the separate reducers into a single one like the following code.
import { combineReducers } from 'redux'
import Reducer1 from './Reducer1.js'
import Reducer2 from './Reducer2.js'
export default combineReducers( { Reducer1, Reducer2,... } )
and use the following code to use that as a single reducer.
import reducers from '../../reducers'(reducer's root folder name/path)
let store = createStore( reducers );

Restrict Access (Meteor + React Router + Roles)

I am trying to implement alanning Meteor-roles with react-router in my Meteor application. Everything is working fine except the fact I can't manage properly to restrict a route using alanning roles or Meteor.user()
I tried with meteor-roles:
I am trying to use the onEnter={requireVerified} on my route. This is the code:
const requireVerified = (nextState, replace) => {
if (!Roles.userIsInRole(Meteor.userId(), ['verified'],'user_default')) {
replace({
pathname: '/account/verify',
state: { nextPathname: nextState.location.pathname },
});
}
};
I tried with Meteor.user():
const requireVerified = (nextState, replace) => {
if (!Meteor.user().isverified == true) {
replace({
pathname: '/account/verify',
state: { nextPathname: nextState.location.pathname },
});
}
};
So this is working when I am clicking on a route link, but when i manually refresh (F5), it does not work. After digging into it, i have found that Meteor.user() is not ready when i manually refresh the page.
I know Meteor.userid() or Meteor.logginIn() are working, but i wanted
to verify not just that they are logged but if they are "verified" or
have a role.
I also tried to check inside the component with react, with componentDidMount() or componentWillMount(), in both cases it's the same, the manual fresh does not load Meteor.user() before the compenent is mounted.
So what is the best way to restrict components/routes with meteor/alaning roles + react router ? (I am using react-komposer inside TheMeteorChef's base)
Thank you.
Note I have not tried it yet, it's only a suggestion
One thing you could try is to use componentWillReceiveProps alongside createContainer from 'react-meteor-data' like that:
import React, { Component, PropTypes } from 'react';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Roles } from 'meteor/alanning:roles';
class MyComponent extends Component {
componentWillReceiveProps(nextProps) {
const { user } = nextProps;
if (user && !Roles.userIsInRole(user._id, ['verified'], 'user_default')) {
browserHistory.push('/account/verify');
}
// If Meteor.user() is not ready, this will be skipped.
}
}
MyComponent.propTypes = {
user: PropTypes.object,
};
export default createContainer(() => {
const user = Meteor.user() || null;
return { user };
}, MyComponent);
To explain the flow, when the page is loaded, as you said Meteor.user() is not defined so you can't check the permissions. However, when Meteor.user() gets defined, this will trigger a refresh of the template, and the new props will be passed to componentWillReceiveProps. At this moment you can check if user has been defined and redirect if needed.
To be really sure not to miss anything, I would actually put the verification in the constructor() as well (defining a function that takes the props as arguments and calling it in both constructor() and componentWillReceiveProps()).

Resources