Why I'm unable to properly authenticate with Google? - javascript

So I'm new to react and I'm trying to authenticate with Google. The problem is every time I try to log in or signup with Google Authentication I'm shown a blank screen with some errors in the console.
This is my App component from where the error originates. The error based on userlocation hook,I guess. Initially, I was getting an error telling me that the location variable is undefined and I fixed that by moving by Router tags in index.js file and it worked. But, now again, its causing error.
import { BrowserRouter as Router, Route,Redirect, Switch } from "react-router-dom";
import './App.css';
import {SignUp,Login,Sidebar,Navbar,Profile} from './components'
import {ResetPassword} from './pages'
import {ResetPasswordConfirm} from './pages'
import {Activate} from './pages'
import {PrivateRoute} from './components'
import {load_user,checkAuthenticated,logout,googleAuthenticate} from './actions/auth'
import {useEffect,useState} from 'react'
import { connect } from 'react-redux';
import {Upload,ClassDiagram,Table,Buttons,Saved} from './pages'
import axios from 'axios'
import {useLocation} from 'react-router-dom'
import queryString from 'query-string'
function App({checkAuthenticated,
load_user,isAuthenticated,
userdata}) {
let location = useLocation()
const [darkmode,setDarkmode] = useState(false);
const [sidebar,setSidebar] = useState(true)
const showSidebar = ()=> {setSidebar(!sidebar)}
const applyDark = () => {
let url = `http://127.0.0.1:8000/profile/update/${userdata?.id}/`;
async function setDarkTheme(){
const resp = await axios.patch(url,{"darktheme":!darkmode})
setDarkmode(!darkmode)
}
setDarkTheme()
}
useEffect(() => {
const values = queryString.parse(location.search)
const state = values.state? values.state : null
const code = values.code? values.code : null
console.log(state)
console.log(code)
if(state && code){
googleAuthenticate(state,code)
}
else{
checkAuthenticated();
load_user();
}
}, [location]);
useEffect(()=>{
if (isAuthenticated){
let url = `http://127.0.0.1:8000/profile/get/${userdata?.id}/`;
async function getDarkTheme(){
const resp = await axios.get(url)
setDarkmode(resp.data.darktheme)
}
getDarkTheme()
}
})
return (
<div>
{isAuthenticated &&
<div className={darkmode?"darkmode":"light"}>
{userdata?
<div>
<Navbar showSidebar={showSidebar}
fullname={userdata.fullname}
darkmode={darkmode}/>
<div className="dashboard">
<Sidebar sidebar={sidebar}
fullname={userdata.fullname}
setDarkmode={applyDark}/>
<Switch>
<Route exact path='/profile'
component={() => <Profile darkmode={darkmode} userdata={userdata}/> } />
<Route exact path='/scanner' component={Upload} />
<Route exact path='/buttons' component={Buttons} />
<Route exact path='/cd'
component={() => <ClassDiagram darkmode={darkmode} id={userdata.id}/> } />
<Route exact path='/sv'
component={()=><Saved id={userdata.id}/>} />
<Route exact path='/table'
component={()=><Table darkmode={darkmode} id={userdata.id}/>} />
<Route exact path='/buttons' component={Buttons} />
</Switch>
</div>
</div>:<h1>Loading</h1>}
</div>
}
<Switch>
<Route exact path='/signup' component={SignUp} />
<Route exact path='/login' component={Login} />
<Route exact path='/reset-password' component={ResetPassword} />
<Route exact path='/password/reset/confirm/:uid/:token' component={ResetPasswordConfirm} />
<Route exact path='/activate/:uid/:token' component={Activate} />
</Switch>
</div>
);
}
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated,
userdata: state.auth.user
});
export default connect(mapStateToProps, {checkAuthenticated,load_user,googleAuthenticate})(App)
This is the image of the error shown in the console. Please guide.
The Error Image
The code for index.js file.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {DataProvider} from './DataContext'
import {Provider} from 'react-redux'
import { BrowserRouter} from "react-router-dom";
import { PersistGate } from 'redux-persist/integration/react'
import configureStore from './store';
const { persistor, store } = configureStore()
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<PersistGate persistor={persistor}>
<DataProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</DataProvider>
</PersistGate>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();

A few things missing here to debug your code.
For a start, make sure you wrap your Router around your App.js like this:
import { BrowserRouter } from "react-router-dom";
<BrowserRouter>
<App />
</BrowserRouter>

Related

Question about PrivateRoutes and to get navigated back to login page

Hi I need help getting my code to work so that when I try to log back in I won't be able to view the dashboard since I logged out. Right now its giving me a blank screen in my project and I think its because privateroute isn't a thing anymore? Not sure. This is my code in PrivateRoute.js:
import React, { Component } from 'react';
import { Route, Navigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
const PrivateRoute = ({ component: Component, auth: { isAuthenticated, loading },
...rest }) => (
<Route {...rest} render={props => !isAuthenticated && !loading ? (<Navigate to='/login' />) : (<Component {...props} />)} />
)
PrivateRoute.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStatetoProps = state => ({
auth: state.auth
});
export default connect(mapStatetoProps)(PrivateRoute);
This is the code for the app.js:
import React, { Fragment, useEffect } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Navbar from './components/layout/Navbar';
import Landing from './components/layout/Landing';
import Register from './components/auth/Register';
import Login from './components/auth/Login';
import Alert from './components/layout/Alert';
import Dashboard from './components/dashboard/Dashboard';
import PrivateRoute from './components/routing/PrivateRoute';
// Redux
import { Provider } from 'react-redux';
import store from './store';
import { loadUser } from './actions/auth';
import setAuthToken from './utils/setAuthToken';
import './App.css';
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const App = () => {
useEffect(() => {
store.dispatch(loadUser());
}, []);
return (
<Provider store={store}>
<Router>
<Fragment>
<Navbar />
<Routes>
<Route exact path='/' element={<Landing/>} />
</Routes>
<section className="container">
<Alert />
<Routes>
<Route exact path='/Register' element={<Register/>} />
<Route exact path='/Login' element={<Login/>} />
<PrivateRoute exact path='/dashboard' element={Dashboard} />
</Routes>
</section>
</Fragment>
</Router>
</Provider>
)};
export default App;
Please Help!
there is a recommended Protected Route implementation in the v6 react router docs you can follow.
DOCS IMPLEMENTATION
Your issue:
<Route {...rest} render={props => !isAuthenticated && !loading ?
(<Navigate to='/login' />) : (<Component {...props} />)} />
This Route is not up to date with v6, which I assume you are using, you need to update it.
Exact is also not supported anymore, there is no point in including it in your routes.
If you are not using v6 please update your post and include your react-router version.

Making the chat widget Tawk.io disappear on one component

I am using a tawk.io chat on my reactjs app:-
This is content of my index.js file:-
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import BookRead from "./pages/BookRead";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Switch>
<Route exact path="/view/:id/:section/:part" component={BookRead} />
<Route component={App} />
</Switch>
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
App.js component file content :-
import React, { useEffect, useState } from "react";
import { Route } from "react-router-dom";
import Login from "./pages/Login";
import Account from "./pages/Account";
import Contact from "./pages/Contact";
import Home from "./pages/Home";
function App(props) {
useEffect(() => {
var Tawk_API = Tawk_API || {},
Tawk_LoadStart = new Date();
(function () {
var s1 = document.createElement("script"),
s0 = document.getElementsByTagName("script")[0];
s1.async = true;
s1.src = "https://embed.tawk.to/5a624e/default";
s1.charset = "UTF-8";
s1.setAttribute("crossorigin", "*");
s0.parentNode.insertBefore(s1, s0);
})();
}, []);
return (
<div className="content">
<div className="container">
<Route exact path="/" component={Home} />
<Route path="/contact-us" component={() => <Contact user={user} />} />
)}
/>
<Route path="/account" component={Account} />
</div>
</div>
);
}
export default App;
How can i show the chat widget in all components inside the App.js route and hide/remove it from the route <Route exact path="/view/:id/:section/:part" component={BookRead} /> ?
Solved by adding the following to BookRead.js component :-
useEffect(() => {
if (window.Tawk_API) {
window.Tawk_API.hideWidget();
}
return () => {
if (window.Tawk_API) {
window.Tawk_API.showWidget();
}
};
}, []);
The API docs at https://developer.tawk.to/jsapi/ suggest you could use Tawk_API.showWidget(); and Tawk_API.hideWidget(); to show and hide the widget.
React-Router provides an useLocation hook you can use to figure out when the location has changed.
Put those two together and you should be able to get the effect you want.

Lazy loaded routes won't show up on route change

I have two routes that I lazy load. Currently when I change route by f.e. using history.push('/') the former route disappears, but the new one won't show up (after reloading it'll show up). How so?
import React, {Suspense, lazy} from 'react';
import './App.scss';
import './modules/Header/Header.scss';
import {Route, Switch} from "react-router-dom";
import Footer from "./modules/Footer/Footer";
const LandingPage = lazy(() => import('./modules/LandingPage/LandingPage'))
const Dashboard = lazy(() => import('./modules/Dashboard/Dashboard'))
function App() {
return (
<div className="App">
<Suspense fallback={<div/>}>
<Switch>
<Route exact path='/' component={LandingPage}/>
<Route path='/dashboard' component={Dashboard}/>
</Switch>
</Suspense>
<Footer/>
</div>
);
}
export default App;
Inside of index.js I initialized Router:
...
import {Router} from 'react-router-dom';
import {createBrowserHistory} from 'history';
export const history = createBrowserHistory();
ReactDOM.render(
<React.StrictMode>
<Router history={history}>
<App/>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
serviceWorker.unregister();
I would like to recommend react-loadable for code splitting dynamic imports.
With react-loadable your code should be like that:
import React from 'react';
import './App.scss';
import './modules/Header/Header.scss';
import {Route, Switch} from "react-router-dom";
import Footer from "./modules/Footer/Footer";
import Loadable from 'react-loadable'
const LoadableLandingPage = Loadable({
loader: () => import('./modules/LandingPage/LandingPage'),
loading() {
return <div>Loading...</div>
},
})
const LoadableDashboard = Loadable({
loader: () => import('./modules/Dashboard/Dashboard'),
loading() {
return <div>Loading...</div>
},
})
function App() {
return (
<div className="App">
<Switch>
<Route exact path='/' component={LoadableLandingPage}/>
<Route path='/dashboard' component={LoadableDashboard}/>
</Switch>
<Footer/>
</div>
);
}
export default App;

React, Javascript - Could not find "store" in the context of "Connect(App)"

I am trying to add propTypes and mapStateToProps to App.js component for React-intl. But it says Could not find "store" in the context of "Connect(App)".
My App.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import jwt_decode from "jwt-decode";
import setAuthToken from "./utils/setAuthToken";
import { setCurrentUser, logoutUser } from "./actions/authActions";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Provider } from "react-redux";
import store from "./store";
import PrivateRoute from "./components/common/PrivateRoute";
import Navbar from "./components/layout/Navbar";
import Footer from "./components/layout/Footer";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
import Main from "./components/main/Main";
import Account from "./components/main/Account";
import { IntlProvider } from "react-intl";
import "./App.css";
// Check for token
if (localStorage.jwtToken) {
// Set auth token header auth
setAuthToken(localStorage.jwtToken);
// Decode token and get user info and exp
const decoded = jwt_decode(localStorage.jwtToken);
// Set user and isAuthenticated
store.dispatch(setCurrentUser(decoded));
// Check for expired token
const currentTime = Date.now() / 1000;
if (decoded.exp < currentTime) {
// Logout user
store.dispatch(logoutUser());
// TODO: Clear current Profile
// Redirect to login
window.location.href = "/login";
}
}
class App extends Component {
render() {
const { lang } = this.props;
return (
<Provider store={store}>
<Router>
<IntlProvider locale={lang}>
<div className="App">
<Navbar />
<Route exact path="/" component={Register} />
<Route exact path="/login" component={Login} />
<Switch>
<PrivateRoute exact path="/dashboard" component={Main} />
<PrivateRoute exact path="/account" component={Account} />
</Switch>
<Footer />
</div>
</IntlProvider>
</Router>
</Provider>
);
}
}
App.propTypes = {
lang: PropTypes.string.isRequired
};
const mapStateToProps = state => ({
lang: state.locale.lang
});
export default connect(mapStateToProps)(App);
Says "Could not find "store" in the context of "Connect(App)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(App) in connect options."
Try to move <Provider /> and <Router /> to index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter, Route } from 'react-router-dom';
import App from './App';
import store from './store';
ReactDOM.render(
<BrowserRouter>
<Provider store={store}>
<Route component={App} />
</Provider>
</BrowserRouter>, document.getElementById('root'));
App.js
class App extends Component {
render() {
const { lang } = this.props;
return (
<IntlProvider locale={lang}>
<div className="App">
<Navbar />
<Route exact path="/" component={Register} />
<Route exact path="/login" component={Login} />
<Switch>
<PrivateRoute exact path="/dashboard" component={Main} />
<PrivateRoute exact path="/account" component={Account} />
</Switch>
<Footer />
</div>
</IntlProvider>
);
}
}

React Router 4 type is invalid

I have updated to the latest version of react/react-router/...
I am now trying to fix the various issues introduced by all the changes to those dependencies.
Note: my code was working before, it is not anymore because of the newer versions.
So I had this to handle my routes before:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import {syncHistoryWithStore, push} from 'react-router-redux';
import configureStore from './store/store';
import App from './components/App';
import EULA from './containers/EULA';
import Main from './containers/Main';
import Blog from './containers/Blog';
const store = configureStore();
const history = syncHistoryWithStore(browserHistory, store);
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<IndexRoute component={Main} />
<Route path="/main" component={Main} />
<Route path="/Feed" component={Blog} />
<Route path="/Blog" component={Blog} />
<Route path="/EULA" component={EULA} />
</Route>
</Router>
</Provider>,
document.getElementById('app')
);
After working on it to fix the history I ended up with what follows. But when I load the site, the content of the navigation bar (declared in App) is shown, but the sub-content of App (ex: Main, or Blog) is not rendered.
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Switch, BrowserRouter, Route, IndexRoute } from 'react-router';
import { createBrowserHistory } from 'history';
import {syncHistoryWithStore, push} from 'react-router-redux';
import configureStore from './store/store';
import App from './components/App';
import Main from './containers/Main';
import Blog from './containers/Blog';
import EULA from './containers/EULA';
const store = configureStore();
const history = syncHistoryWithStore(createBrowserHistory(), store);
ReactDOM.render(
<Provider
store={store}>
<Router
history={history}>
<Switch>
<Route exact path="/" component={App} />
<Route path="/main" component={Main} />
<Route path="/Feed" component={Blog} />
<Route path="/Blog" component={Blog} />
<Route path="/EULA" component={EULA} />
<Redirect to="/" />
</Switch>
</Router>
</Provider>,
document.getElementById('app')
);
After further investigations I found this site that describe how to migrate to Router 4.
So I tried it and cannot make the example work.
This is what I have now:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route } from 'react-router';
const PrimaryHeader = props => {
return (
<header>
Our React Router 4 App
</header>
)
}
const HomePage =() => <div>Home Page</div>
const UsersPage = () => <div>Users Page</div>
const UserAddPage = () => <div>Users Add Page</div>
const PrimaryLayout = props => {
return (
<div className="primary-layout">
<PrimaryHeader />
<main>
<Switch>
<Route path="/" exact component={HomePage} />
<Route path="/users/add" component={UserAddPage} />
<Route path="/users" component={UsersPage} />
<Redirect to="/" />
</Switch>
</main>
</div>
)
}
const App = () => (
<BrowserRouter>
<PrimaryLayout />
</BrowserRouter>
)
ReactDOM.render(
<App />,
document.getElementById('app'));
When I compile and get onto the site I see the following in the console:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
in App
Check the render method of `App`.
at invariant (invariant.js:42)
at createFiberFromElement (react-dom.development.js:5753)
at reconcileSingleElement (react-dom.development.js:7531)
at reconcileChildFibers (react-dom.development.js:7635)
at reconcileChildrenAtExpirationTime (react-dom.development.js:7756)
at reconcileChildren (react-dom.development.js:7747)
at mountIndeterminateComponent (react-dom.development.js:8075)
at beginWork (react-dom.development.js:8221)
at performUnitOfWork (react-dom.development.js:10224)
at workLoop (react-dom.development.js:10288)
I have done some further test (using my version that I fixed).
In App render function I was getting the children and rendering them.
Now it seems that children is undefined.
I would venture a guess that it has to do with the fact that in the older version the other routes were children of the "/" {App} route. And that before of the way Router 4 is now it is not the case anymore.
I will have to move children inside main I guess?
But that still does not explain why the simpler example is not working.
It seems like there is something off in your imports. If you delete your node_modules are rerun yarn install (or npm install) the compilation should alert you already.
The following code works fine (and as expected for me)
import React from 'react';
import ReactDOM from 'react-dom';
import {Redirect, Route, Switch} from 'react-router';
import {BrowserRouter} from "react-router-dom";
const PrimaryHeader = props => {
return (
<header>
Our React Router 4 App
</header>
)
};
const HomePage = () => <div>Home Page</div>;
const UsersPage = () => <div>Users Page</div>;
const UserAddPage = () => <div>Users Add Page</div>;
const PrimaryLayout = props => {
return (
<div className="primary-layout">
<PrimaryHeader/>
<main>
<Switch>
<Route path="/" exact component={HomePage}/>
<Route path="/users/add" component={UserAddPage}/>
<Route path="/users" component={UsersPage}/>
<Redirect to="/"/>
</Switch>
</main>
</div>
)
};
const App = () => (
<BrowserRouter>
<PrimaryLayout/>
</BrowserRouter>
);
ReactDOM.render(
<App/>,
document.getElementById('root'));
Changes were:
Import BrowserRouter from react-router-dom
Add missing imports
This was done with react-router 4.2 and react-router-dom 4.2.2

Categories

Resources