Error logging in: onLoginSuccess is not a function

  • JavaScript
  • Thread starter Pyrexx
  • Start date
  • Tags
    Function
  • #1
Pyrexx
5
0
TL;DR Summary
I am trying to call a function from another JS File, but the error "Error logging in: onLoginSuccess is not a function" keeps popping up
This is the component for Authors to Login to the Web Application

JavaScript:
import { Button, CircularProgress, Fade, Link, TextField, Typography } from '@material-ui/core';
import { ThemeProvider, createTheme, makeStyles } from '@material-ui/core/styles';
import axios from 'axios';
import React, { useState } from 'react';
import { Link as RouterLink, useNavigate } from 'react-router-dom';
import backgroundImage from './background.jpg';
import ParentComponent from './ParentComponent';

const theme = createTheme({
    palette: {
        primary: {
            main: '#00bcd4', // Cyan color
        },
        error: {
            main: '#ff1744', // Error color
        },
    },
});
const useStyles = makeStyles((theme) => ({
    root: {
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        minHeight: '100vh',
        backgroundImage: `url(${backgroundImage})`,
        backgroundSize: 'cover',
        backgroundPosition: 'center',
    },
    formContainer: {
        maxWidth: 400,
        width: '100%',
        padding: theme.spacing(4),
        borderRadius: theme.shape.borderRadius,
        boxShadow: theme.shadows[5],
        backgroundColor: '#fff',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    form: {
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    textField: {
        width: '100%',
        marginBottom: theme.spacing(3),
    },
    button: {
        marginTop: theme.spacing(2),
        width: '100%',
        maxWidth: 200,
        padding: theme.spacing(1.5),
    },
    title: {
        fontFamily: 'Roboto, sans-serif',
        fontWeight: 700,
        fontSize: '2.5rem',
        color: theme.palette.primary.main,
        marginBottom: theme.spacing(3),
        textAlign: 'center',
        textShadow: '2px 2px 4px rgba(0, 0, 0, 0.3)',
    },
    error: {
        marginTop: theme.spacing(2),
        color: theme.palette.error.main,
        textAlign: 'center',
    },
    link: {
        marginTop: theme.spacing(2),
        textAlign: 'center',
    },
}));
const AuthorLogin = ({ onLoginSuccess, onLoginError }) => { // Accept onLoginSuccess as a prop
    const classes = useStyles();
    const navigate = useNavigate();
    const [formData, setFormData] = useState({
        email: '',
        password: '',
    });
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');
    const handleChange = (e) => {
        setFormData({ ...formData, [e.target.name]: e.target.value });
    };
    const handleSubmit = async (e) => {
        e.preventDefault();
        setLoading(true);
        try {
            const response = await axios.post('http://localhost:5000/api/author/login', formData);
            console.log('Login successful:', response.data);
            // Redirect to writing portfolio upon successful login
            navigate('/writingPortfolio');
            console.log("Calling onLoginSuccess...");
 // Log the type of onLoginSuccess
            onLoginSuccess(); // Attempt to call onLoginSuccess // Call onLoginSuccess upon successful login
        } catch (error) {
            onLoginError(error.message);
            console.error('Error logging in:', error.response ? error.response.data.message : error.message);
            setError(error.response ? error.response.data.message : error.message);
        }
        setLoading(false);
    };
    return (
        <div className={classes.root}>
            <Fade in={true} timeout={1500}>
                <div className={classes.formContainer}>
                    <ThemeProvider theme={theme}>
                        <Typography variant="h1" className={classes.title}>
                            Author Login
                        </Typography>
                        <form onSubmit={handleSubmit} className={classes.form}>
                            <TextField
                                type="email"
                                label="Email"
                                name="email"
                                value={formData.email}
                                onChange={handleChange}
                                variant="outlined"
                                className={classes.textField}
                                required
                                placeholder="Enter your email"
                            />
                            <TextField
                                type="password"
                                label="Password"
                                name="password"
                                value={formData.password}
                                onChange={handleChange}
                                variant="outlined"
                                className={classes.textField}
                                required
                                placeholder="Enter your password"
                            />
                            <Button
                                type="submit"
                                variant="contained"
                                color="primary"
                                className={classes.button}
                                disabled={loading}
                            >
                                {loading ? <CircularProgress size={24} color="inherit" /> : 'Login'}
                            </Button>
                            {error && <Typography variant="body2" className={classes.error}>{error}</Typography>}
                        </form>
                        <Typography variant="body2" className={classes.link}>
                            Don't have an account?{' '}
                            <Link component={RouterLink} to="/AuthorRegistration">
                                Sign up
                            </Link>
                        </Typography>
                    </ThemeProvider>
                </div>
            </Fade>
        </div>
    );
};
export default AuthorLogin;





This is the parent component used to help handle authors updating their details and authentication for authors to get access to respective parts of the pages

This is where the function is defined and where I want to call the function from but with no success, despite me trying everything
```
Parent Component:
// ParentComponent.js
import React, { useState } from 'react';
import AuthorDashboard from './AuthorDashboard';
import AuthorLogin from './AuthorLogin';
import AuthorProfile from './AuthorProfile';
import AuthorSettings from './AuthorSettings';
const ParentComponent = () => {
    const [author, setAuthor] = useState(null);
    const [isAuthenticated, setIsAuthenticated] = useState(false);
    const [error, setError] = useState(null);
    const handleUpdateAuthor = (updatedAuthor) => {
        setAuthor(updatedAuthor);
    };
    const handleLoginSuccess = async () => {
        setIsAuthenticated(true);
        try {
            const response = await fetch('/author');
            const author = await response.json();
            setAuthor(author);
            setError(null);
            console.log("handleLoginSuccess is a function:", typeof handleLoginSuccess === "function");
            // Clear any previous errors on successful login
        } catch (error) {
            console.error('Error handling login success:', error);
            setError('An error occurred while handling login success.');
        }
    };
    
    function handleLoginError (errorMessage) {
        setError(errorMessage);
    };
    
    
    return (
        <div>
            {isAuthenticated ? (
                <>
                    <AuthorSettings author={author} onUpdateAuthor={handleUpdateAuthor} />
                    <AuthorProfile author={author} />
                    <AuthorDashboard isAuthenticated={isAuthenticated} authorId={author.id} />
                </>
            ) : (
                <AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
            )}
            {error && <p style={{ color: 'red' }}>{error}</p>}
        </div>
    );
};
export default ParentComponent;
```
 
Technology news on Phys.org
  • #2
Does the error message include the number 97? That's the line number in the first batch of code you posted. That line has onLoginSuccess();

Also in the first batch of code, line 75 defines AuthorLogin. I haven't done any JavaScript for more than 20 years, but it seems to me that the rest of the code on this line is for an anonymous function that takes an enumeration whose values are onLoginSuccess and onLoginError. If I'm correct here, these aren't functions but instead are values of an enumeration.

Finally, line 43 of the second batch of code has this:
JavaScript:
<AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
Shouldn't there be a comma or other separator between the expressions with onLoginSuccess and onLoginError?
 
  • #3
Mark44 said:
Does the error message include the number 97? That's the line number in the first batch of code you posted. That line has onLoginSuccess();

Also in the first batch of code, line 75 defines AuthorLogin. I haven't done any JavaScript for more than 20 years, but it seems to me that the rest of the code on this line is for an anonymous function that takes an enumeration whose values are onLoginSuccess and onLoginError. If I'm correct here, these aren't functions but instead are values of an enumeration.

Finally, line 43 of the second batch of code has this:
JavaScript:
<AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
Shouldn't there be a comma or other separator between the expressions with onLoginSuccess and onLoginError?
Yeah there are also error messages for the onLoginSuccess(); as it isn't being seen as a function

I am new to Javascript, I thought I defined the
HandleLoginSuccess and HandleLoginError as functions and assigned onLoginSuccess and onLoginError to them

Correct me if I'm wrong but I though you don't need to add a separator between the props
 
  • #4
Line 75 and following:
JavaScript:
const AuthorLogin = ({ onLoginSuccess, onLoginError }) => { // Accept onLoginSuccess as a prop
    const classes = useStyles();
    const navigate = useNavigate();
    const [formData, setFormData] = useState({
        email: '',
        password: '',
    });
It doesn't seem to me that onLoginSuccess and onLoginError are defined anywhere. I would think that these are event handlers that need to be attached to some function definitions somewhere.

In lines 97 and 99 you attempt to call onLoginSuccess() and onLoginError(), the first of which generates the error you reported.

The other line of code that I mentioned, in the second snippet you posted is this:
JavaScript:
<AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
Again, I'm thinking that there should be a separator after {handleLoginSuccess} and before onLoginError, like maybe a semicolon - ;

Presumably the code in the second snippet executes before the code of the first snippet, and if so, it would associate the names onLoginSuccess and onLoginError with functions (event handlers). If the separator is required, but missing, the compiler will be confused and not make those connections.

What you're working with combines Javascript together with HTML and CSS. These have different rules for how to combine items in a list, so a rule that might apply to HTML or CSS probably is different for Javascript.
 
  • #5
Mark44 said:
Line 75 and following:
JavaScript:
const AuthorLogin = ({ onLoginSuccess, onLoginError }) => { // Accept onLoginSuccess as a prop
    const classes = useStyles();
    const navigate = useNavigate();
    const [formData, setFormData] = useState({
        email: '',
        password: '',
    });
It doesn't seem to me that onLoginSuccess and onLoginError are defined anywhere. I would think that these are event handlers that need to be attached to some function definitions somewhere.

In lines 97 and 99 you attempt to call onLoginSuccess() and onLoginError(), the first of which generates the error you reported.

The other line of code that I mentioned, in the second snippet you posted is this:
JavaScript:
<AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
Again, I'm thinking that there should be a separator after {handleLoginSuccess} and before onLoginError, like maybe a semicolon - ;

Presumably the code in the second snippet executes before the code of the first snippet, and if so, it would associate the names onLoginSuccess and onLoginError with functions (event handlers). If the separator is required, but missing, the compiler will be confused and not make those connections.

What you're working with combines Javascript together with HTML and CSS. These have different rules for how to combine items in a list, so a rule that might apply to HTML or CSS probably is different for Javascript.
1713380867574.png

This is the error I get when I try to add a seperator

Also how do I define onLoginSuccess and onLoginError because I thought I already defined it in the Parent Component. So how do I fix it?

Thank you very much
 
  • #6
Pyrexx said:
This is the error I get when I try to add a seperator
Does using a comma as the separator work?
Pyrexx said:
Also how do I define onLoginSuccess and onLoginError because I thought I already defined it in the Parent Component. So how do I fix it?
Here's the code, in ParentComponent, where onLoginSuccess and onLoginError are defined.
JavaScript:
<div>
            {isAuthenticated ? (
                <>
                    <AuthorSettings author={author} onUpdateAuthor={handleUpdateAuthor} />
                    <AuthorProfile author={author} />
                    <AuthorDashboard isAuthenticated={isAuthenticated} authorId={author.id} />
                </>
            ) : (
                <AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
            )}
            {error && <p style={{ color: 'red' }}>{error}</p>}
        </div>
If isAuthenticated is false, the block following : should execute. My best guess is that what is needed is a comma before onLoginError in the AuthorLogin line.

If that doesn't work, I don't have any more advice but would advise you to look for some working code that is similar in how it handles errors.
 
  • #7
Mark44 said:
Does using a comma as the separator work?

Here's the code, in ParentComponent, where onLoginSuccess and onLoginError are defined.
JavaScript:
<div>
            {isAuthenticated ? (
                <>
                    <AuthorSettings author={author} onUpdateAuthor={handleUpdateAuthor} />
                    <AuthorProfile author={author} />
                    <AuthorDashboard isAuthenticated={isAuthenticated} authorId={author.id} />
                </>
            ) : (
                <AuthorLogin onLoginSuccess={handleLoginSuccess} onLoginError={handleLoginError} />
            )}
            {error && <p style={{ color: 'red' }}>{error}</p>}
        </div>
If isAuthenticated is false, the block following : should execute. My best guess is that what is needed is a comma before onLoginError in the AuthorLogin line.

If that doesn't work, I don't have any more advice but would advise you to look for some working code that is similar in how it handles errors.
Adding a comma shows the same error
 
  • #8
Pyrexx said:
Adding a comma shows the same error
Yes, neither a comma or anything else belongs there.

@Mark44 this is not plain JavaScript, it is a mix of JavaScript and JSX written for compilation by the React build process.

There are not many of us here on PF that know React, and I can't work out what is wrong on my phone, so this is probably not the best place to seek help: try the official React tutorial https://react.dev/learn/responding-to-events
 
  • Informative
Likes Mark44
  • #9
pbuk said:
Yes, neither a comma or anything else belongs there.

@Mark44 this is not plain JavaScript, it is a mix of JavaScript and JSX written for compilation by the React build process.

There are not many of us here on PF that know React, and I can't work out what is wrong on my phone, so this is probably not the best place to seek help: try the official React tutorial https://react.dev/learn/responding-to-events
I've tried but with no luck

Is there anyone you know that could help me with this?
Thanks for your time
 
Back
Top