'login' is not defined error happens in React.js - javascript

I made frontend app in React.js.
I wrote codes in App.js of frontend like
import React, { Fragment, useState, useEffect, Component, View } from 'react';
import axios from 'axios';
import Routes from '../src/components/Routes';
import TopNavigation from './components/topNavigation';
import SideNavigation from './components/sideNavigation';
import Footer from './components/Footer';
import './index.css';
import Router from './Router';
const App = () => {
const [user, setLogin] = useState(null)
const [report, setReport] = useState(null)
useEffect(()=>{
login().then(user => setLogin(user))
}, [])
useEffect(()=>{
getReport().then(report => setReport(report))
}, [])
return <div>
{user != null? <p>name: {user.name}</p>:<button>Login</button>}
</div>
}
export default App;
I wrote in this code login().then(user => setLogin(user)) whether user already logined or not.
Login system was made in Django,so I want to use it.I think React has login method but I really cannot understand what is wrong.How should I fix this?

I can see nowhere login is defined in your code. If you've written login on other files, you should import it.
Actually, I cannot understand what you mean by this - "I think React has login method but ...". React doesn't support any predefined login method.
You should define login method yourself something like this.
const API_URL = 'some url';
const login = async (body) => {
const response = await axios.post(`${API_URL}/login`, body);
return response.json();
};
const App = () => {
const [user, setLogin] = useState(null);
const [report, setReport] = useState(null);
useEffect(() => {
login({
email: 'email#some.com',
password: 'some password'
}).then((user) => setLogin(user));
}, []);
useEffect(() => {
getReport().then((report) => setReport(report));
}, []);
};

Related

React Native (React Navigation)<> Firebase login screen

I'm using Firebase to keep track of all the users. I was able to connect Firebase. User registration is working fine.
I'm having issues with logging the users. When I enter login and password, the app doesn't redirect me to the right screen, and also throws this warning [Unhandled promise rejection: TypeError: navigation.navigation is not a function. (In 'navigation.navigation("myProfile")', 'navigation.navigation' is undefined)]
Here is how I do it
import { useNavigation } from "#react-navigation/native";
import React, { useEffect, useState } from "react";
import { View, ...} from "react-native";
import { auth } from "../firebase";
const Profile = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const navigation = useNavigation();
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
navigation.navigation("myProfile");
}
});
return unsubscribe;
}, []);
const signIn = () => {
auth
.signInWithEmailAndPassword(email, password)
.then((userCredentials) => {
const user = userCredentials.user;
console.log("Sign In user.email = " + user.email);
})
.catch((error) => alert(error.message));
};
//more code
I also tried this, but it didn't help
import React, { useEffect, useState } from "react";
import { View, ...} from "react-native";
import { auth } from "../firebase";
const Profile = ({navigation}) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
if (user) {
navigation.navigation("myProfile");
}
});
return unsubscribe;
}, []);
//more code
I'm not sure if I need to navigation.navigation("myProfile") onPress or it has to be inside of the the useEffect
Use
navigation.navigate("myProfile")
instead of
navigation.navigation("myProfile");
Also you can destruct your hook object like this
const { navigate } = useNavigation()
in order to just write
navigate("myProfile")
I'm not sure if I need to navigation.navigation("myProfile") onPress or it has to be inside of the the useEffect
Most of the cases you should move the user to home screen (logged in user screen) when the signIn function returns true and the user is logged in, so in this case I think you have to use navigate("myProfile") inside of
auth
.signInWithEmailAndPassword(email, password)
.then((userCredentials) => {
...your code
navigation.navigate("myProfile")
})

React Hook useEffect contains a call to & missing dependencies

So we have a an issue here when running NPM start, this is what I have received warnings when compiling, can't for the life of me figure this one out, this is my first ever question after years of using StackOverflow. I have now included my app.js and index.js, I'm sure i am doing something else wrong too as when I include //eslint-disable-next-line to all pages mentioned the localhost shows a white screen.
React Hook useEffect contains a call to 'setNewDevice'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [finishConfirmation] as a second argument to the useEffect Hook.
const Confirmed = props => {
const [newDevice, setNewDevice] = useState(false);
const [complete, setComplete] = useState(false);
const db = firebase.firestore();
useEffect(() => {
let email = window.localStorage.getItem("confirmationEmail");
if (!email) {
setNewDevice(true);
} else {
finishConfirmation(email);
}
});
React Hook useEffect has missing dependencies: 'moreInfoComplete', 'requestNotifications', and 'userState.userData.firstName'. Either include them or remove the dependency array.
const Dashboard = () => {
const [firstName, setFirstName] = useState(null);
const [lastName, setLastName] = useState(null);
const [moreInfoComplete, setMoreInfoComplete] = useState(false);
const { userState, userDispatch } = useContext(UserContext);
const { sendMessage } = useContext(ToastContext);
const db = firebase.firestore();
useEffect(() => {
if (
(moreInfoComplete || userState.userData.firstName) &&
"Notification" in window &&
Notification.permission === "default"
) {
requestNotifications();
}
}, []);
React Hook useEffect has missing dependencies: 'db', 'userDispatch', and 'userState.userData.pushTokenWeb'. Either include them or remove the dependency array.
const MainRouter = () => {
const [initializationComplete, setInitComplete] = useState(false);
const { userState, userDispatch } = useContext(UserContext);
const userId = userState.userId;
const db = firebase.firestore();
useEffect(() => {
sendPushNotification({
token: userState.userData.pushTokenWeb,
title: "Boop",
body: "shoop"
});
App.js
import React from "react";
import { ToastProvider } from "./contexts/toastContext";
import { UserProvider } from "./contexts/userContext";
import MainRouter from "./MainRouter";
const App = () => {
return (
<ToastProvider>
<UserProvider>
<MainRouter />
</UserProvider>
</ToastProvider>
);
};
export default App;
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();

ReactJS rendering Issue fetching an API

I'm trying to fetch a WeatherApp API, using Geolocation.
My problem is the rendering:
It doesn't allow me to render the page before I fetch (but after I somehow manage to fetch, the code seems to work).
Returning Error message:
Type Error : Cannot Read Property 'temp' of undefined
import React, { useState } from 'react';
import './App.css';
import Axios from 'axios';
function App() {
const [ positionLat, setPositionLat ] = useState('') ;
const [ positionLong, setPositionLong] = useState('') ;
navigator.geolocation.getCurrentPosition(function(position) {
setPositionLat(position.coords.latitude);
setPositionLong(position.coords.longitude);
});
const [weather, setWeather] = useState('');
const fetchingWeather = () => {
Axios.get(
`https://api.openweathermap.org/data/2.5/weather?lat=${positionLat}&lon=${positionLong}&appid={API_KEY}&units=metric`)
.then((res) => {
console.log(res.data.main.temp)
setWeather(res.data)
})
}
// this line is returning the error
console.log(weather.main.temp)
return (
<div className="App">
<p>lattitude :{positionLat}</p>
<p>longitude :{positionLong}</p>
<button onClick={fetchingWeather}>Cliquez moi pour fetch</button>
</div>
);
}
export default App;
Fetching weather and setting weather state is asynchronous, your are console logging weather.main.temp before the request has completed. And fetching data is side effect in reactjs. So you are suggested to fetch weather info by using useEffect hooks and set weather state there.
import React, { useState, useEffect } from 'react';
import './App.css';
import Axios from 'axios';
function App() {
const [ positionLat, setPositionLat ] = useState('') ;
const [ positionLong, setPositionLong] = useState('') ;
navigator.geolocation.getCurrentPosition(function(position) {
setPositionLat(position.coords.latitude);
setPositionLong(position.coords.longitude);
});
const [weather, setWeather] = useState('');
const fetchingWeather = () => {
Axios.get(
`https://api.openweathermap.org/data/2.5/weather?lat=${positionLat}&lon=${positionLong}&appid={API_KEY}&units=metric`)
.then((res) => {
console.log(res.data.main.temp)
setWeather(res.data)
})
}
useEffect(() => {
fetchingWeather();
}, [weather])
return (
<div className="App">
<p>lattitude :{positionLat}</p>
<p>longitude :{positionLong}</p>
<button onClick={fetchingWeather}>Cliquez moi pour fetch</button>
</div>
);
}
export default App;
That should work.

Get logged user every time the component renders under React ContextAPI

I'm using ContextAPI in a small React project, I use HttpOnly Cookie to store the user's token when I hit the /login endpoint.
This is UserContext.js shown bellow, which encapsulates all the components (children) in App.js
import axios from "axios";
import { createContext, useEffect, useState } from "react";
const UserContext = createContext();
const UserContextProvider = ({ children }) => {
const [loggedUser, setLoggedUser] = useState(undefined);
const checkLoggedIn = async () => {
const response = await axios.get(`${process.env.REACT_APP_URL}/logged-in`);
setLoggedUser(response.data);
};
useEffect(() => {
checkLoggedIn();
}, []);
return (
<UserContext.Provider value={{ loggedUser }}>
{children}
</UserContext.Provider>
);
};
export { UserContext };
export default UserContextProvider;
What I understand is when I log in, I setLoggedUser to the state from the /login response, and now it is available for all the children components of the context.
Now I can navigate to all components wrapped by the context and print for example the email of the loggedUser, but what if the email changed while we're logged in? I'll still see the old email on my components because the data is outdated in the state. And what if token got invalidated on the server while we were logged in.. (The only case we'll get updated data is if I refresh the app because that will trigger useEffect in the context provider and refresh the state again)
Should I also pass the checkLoggedIn function through the context's value property to make it available for other components and then use it in UseEffect in every component? Or is there a better solution for this problem?
After the latest comment if you want to check for email on every re-render then you can remove [] from useEffect as stated above in the comments by #abu dujana.
import axios from "axios";
import { createContext, useEffect, useState } from "react";
const UserContext = createContext();
const UserContextProvider = ({ children }) => {
const [loggedUser, setLoggedUser] = useState(undefined);
const checkLoggedIn = async () => {
const response = await axios.get(`${process.env.REACT_APP_URL}/logged-in`);
setLoggedUser(response.data);
};
useEffect(() => {
checkLoggedIn();
});
return (
<UserContext.Provider value={{ loggedUser }}>
{children}
</UserContext.Provider>
);
};
export { UserContext };
export default UserContextProvider;

Next.js Example Auth - re-routing based on auth, wrapping around other functions

I'm trying to use the next.js with authentication for a small project. The authentication currently works but doesn't allow me to show the data in my navbar.
I was using it with firebase originally BUT NOT ANYMORE!! Now have the authentication set up separately below.
This is the example repo, it has my API in it for auth and the next.js, which i'm trying to integrate together to have login and logout working with header's set for api calls.
https://github.com/Hewlbern/example
Just getting the basic login and logout functionality, so I can control user access to my website. I know this is really simple - just quite confused how to do it with next.js with how document page an app works :S
I am trying to show a table of output from this API, and give the ability to download the outputed json (into a CSV or whatever). So having that available after a search with the query params, and only on a page after the user is logged in, is the point :)
Here's an example of the login functionality I'm using.
import { useRef, useState } from 'react';
import React from 'react'
import PropTypes from 'prop-types'
import Layout from "../components/Layout";
export default function Login() {
const emailRef = useRef<HTMLInputElement>(null);
const passRef = useRef<HTMLInputElement>(null);
const [message, setMessage] = useState<any>(null);
async function handleLogin() {
const resp = await fetch('http://localhost:3001/auth/login', {
method: 'POST',
headers: {
'Content-Type': "application/x-www-form-urlencoded"
},
body: JSON.stringify({
email: emailRef.current?.value,
password: passRef.current?.value
})
});
const json = await resp.json();
setMessage(json);
}
return (
<Layout>
{JSON.stringify(message)}
<input type="text" placeholder="email" ref={emailRef} />
<input type="password" placeholder="password" ref={passRef} />
<button onClick={handleLogin}>Login</button>
</Layout>
);
}
This is posting to this api request
router.post('/login', (req, res) => {
// console.log(req.body)
let email = req.body.email;
let password = req.body.password;
console.log(email,password)
DatabaseService.GetUser(email).then(user => {
if(user===null){
res.sendStatus(404);
}
else{
if(bcrypt.compareSync(password, user[0].password)) {
jwt.sign({user}, 'secretkey', { expiresIn: '30d' }, (err, token) => {
DatabaseService.SetSession(token,JSON.stringify(user[0].user_id)).then(inserted=>{
res.json({
token
});
});
});
} else {
res.sendStatus(500);
}
}
});
});
So just with this small example, hat's wrong with how I'm sending the requests currently? (thinking it's the format the login takes requests in?)
If someone has done something similar or knows how to solve these issues, I'd really appreciate it :)
Cheers!
What I'd recommend here is to create a custom hook which makes use of React's Context API in order to "monitor" the auth state changing. Then wrap you app in that provider and you'll have the flexibility do anything you want with that auth state using your new custom hook.
Here's an example of how that custom hook would look using a authentication with Firebase:
import React, { createContext, useContext, useState } from 'react'
import { auth } from './services' // this is just firebase.auth()
const UserContext = createContext()
export const UserProvider = ({ children }) => {
const [user, setUser] = useState(undefined)
auth.onAuthStateChanged(setUser)
return <UserContext.Provider value={user}>{children}</UserContext.Provider>
}
export const useUser = () => useContext(UserContext)
Now you just need to wrap your app in the UserProvider.
Like this:
import React, { StrictMode } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './app'
import { UserProvider } from './hooks'
const rootElement = document.getElementById('root')
ReactDOM.render(
<StrictMode>
<BrowserRouter>
<UserProvider>
<App />
</UserProvider>
</BrowserRouter>
</StrictMode>,
rootElement
)
Then as an example, let's say you wanted to automatically direct away from your Login page if the use is logged it. You could make use of the useEffect hook, and useHistory hooks to navigate to / if the user is logged in.
Something like this will do:
import React, { useEffect } from 'react'
import { useHistory } from 'react-router-dom'
import { useUser } from './hooks'
const LoginPage = () => {
const history = useHistory()
const user = useUser() // user is undefined if not logged in
useEffect(() => {
if (user) { // will run the condition if user exists
history.push('/')
}
}, [user])
...
}
You could go on to actually use the user data in your navigation bar using something like this:
import React from 'react'
import { Link } from 'react-router-dom'
import { useUser } from './hooks'
const NavBar = () => {
const user = useUser()
return (
<div>
{user ?
<Link to="/profile">Welcome, {user.displayName}</Link> :
<Link to="/login">Login</Link>
}
</div>
)
}
Obviously you can change this for us according to your own needs, but all this should get you going with how work with authentication state in a clean robust manner.

Categories