Search code examples
jsonauthenticationionic-frameworktokenionic4

Ionic gives error undefined is not an object (evaluating '_co.user.username') when decoding the login user token


This is part of the error message that I am getting:

[Error] ERROR – TypeError: undefined is not an object (evaluating '_co.user.username') TypeError: undefined is not an object (evaluating '_co.user.username')(anonymous function)checkAndUpdateView — core.js:44...

My login process works fine and data of the user is gotten fine, on ionic serve version of my app, but on ios I can see that error message, like json encoding doesn't work fine or something. Why is the JSON working fine on website, but not on the app? Here is content of TokenService :

    constructor(private cookieService: CookieService) {}

    setToken(token) {
        this.cookieService.set("chat_token", token);
    }

    getToken() {
        return this.cookieService.get("chat_token");
    }

    deleteToken() {
        this.cookieService.delete("chat_token");
    }

    getPayload() {
        const token = this.getToken();
        let payload;
        if (token) {
            payload = token.split(".")[1];
            payload = JSON.parse(window.atob(payload));
        }

        return payload.data;
    }

and this is the loginUser function in LoginComponent , that is triggered on logging in:

loginUser() {
        this.showSpinner = true;

        this.authService.loginUser(this.loginForm.value).subscribe(
            data => {
                this.tokenService.setToken(data.token);
                localStorage.setItem("currentUser", JSON.stringify(data));

                this.loginForm.reset();

                setTimeout(() => {
                    this.router.navigate(["/streams"]);
                }, 200);
            },
            err => {
                this.showSpinner = false;

                if (err.error.message) {
                    this.errorMessage = err.error.message;
                }
            }
        );
    }

Now, the server side, I have this rout in routes/ directory, in node express in file authRoutes.js:

router.post('/login', AuthCtrl.LoginUser);

And then I have this in routes/ directory, in file userRoutes.js:

const express = require('express');

const router = express.Router();

const UserCtrl = require('../controllers/users');
const AuthHelper = require('../Helpers/AuthHelper');

router.get('/users', AuthHelper.VerifyToken, UserCtrl.GetAllUsers);
router.get('/user/:id', AuthHelper.VerifyToken, UserCtrl.GetUser);
router.get(
  '/username/:username',
  AuthHelper.VerifyToken,
  UserCtrl.GetUserByName
);
router.post('/user/view-profile', AuthHelper.VerifyToken, UserCtrl.ProfileView);
router.post(
  '/change-password',
  AuthHelper.VerifyToken,
  UserCtrl.ChangePassword
);

module.exports = router;

This is the part of controller auth.js on node server side:

    async LoginUser(req, res) {
        if (!req.body.username || !req.body.password) {
            return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: "No empty fields allowed" });
        }

        await User.findOne({ username: Helpers.firstUpper(req.body.username) })
            .then(user => {
                if (!user) {
                    return res.status(HttpStatus.NOT_FOUND).json({ message: "Username not found" });
                }

                return bcrypt.compare(req.body.password, user.password).then(result => {
                    if (!result) {
                        return res
                            .status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .json({ message: "Password is incorrect" });
                    }
                    const token = jwt.sign({ data: user }, dbConfig.secret, {
                        expiresIn: "5h"
                    });
                    res.cookie("auth", token);
                    return res.status(HttpStatus.OK).json({ message: "Login successful", user, token });
                });
            })
            .catch(err => {
                console.log("Error is:");
                console.log(err);
                return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: "Error occured" });
            });
    }

Solution

  • I resolved the issue by transferring all the stored data from CookieService, which is the main culprit of the error, to a localStorage. Just instead of storing payload and that cookie in CookieService, just transferred it to localStorage, and I didn't have any more problems. Seems like, the simpler - the better.