Reputation: 470
I am looking for a response from userService .. but it is returning a null value.. I have consoled the data in userSerice it's showing here.
may be my controller is giving a response before receiving value from userService.
how can I solve this?
usercontroller
import {
Controller,
Post,
Body,
Get,
Param,
Patch,
Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Post('/login')
async login(
@Body('email') userEmail,
@Body('password') userPassword
) {
const token = await this.userService.Login(userEmail, userPassword)
console.log(token, 'token')
return token;
}
}
Userservice :
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import * as jwt from 'jsonwebtoken';
import { Model } from 'mongoose';
import { User } from './user.model';
import * as bcrypt from 'bcrypt'
import { resolve } from 'dns';
@Injectable()
export class UserService {
constructor(
@InjectModel('User') private readonly userModel: Model<User>,
) { }
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
bcrypt.compare(password, user.password, function (err, result) {
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = jwt.sign({ name: user.name, email: user.email, role: user.role }, "testSecreate");
const response = { name: user.name, email: user.email, role: user.role, token: authJwtToken }
console.log(response)
return response;
});
}
}
Upvotes: 0
Views: 1034
Reputation: 70151
Tushar has n all right answer, but it's still mixing promises and callbacks, which I think should be avoided if possible. You can use this instead to not have any callbacks and just use async/await
and promises throughout the method
import {
Injectable,
NotFoundException,
UnauthorizedException,
} from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import * as jwt from "jsonwebtoken";
import { Model } from "mongoose";
import { User } from "./user.model";
import * as bcrypt from "bcrypt";
@Injectable()
export class UserService {
constructor(@InjectModel("User") private readonly userModel: Model<User>) {}
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
const result = await bcrypt.compare(password, user.password);
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = await jwt.sign(
{ name: user.name, email: user.email, role: user.role },
"testSecreate"
);
const response = {
name: user.name,
email: user.email,
role: user.role,
token: authJwtToken,
};
console.log(response);
return response;
}
}
Now, the console.log(response)
will fire before console.log('token', token)
in your controller method, and the flow will look synchronous while actually being asynchronous in nature.
Upvotes: 1
Reputation:
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import * as jwt from 'jsonwebtoken';
import { Model } from 'mongoose';
import { User } from './user.model';
import * as bcrypt from 'bcrypt'
import { resolve } from 'dns';
@Injectable()
export class UserService {
constructor(
@InjectModel('User') private readonly userModel: Model<User>,
) { }
async Login(email: string, password: string) {
const user = await this.userModel.findOne({ email });
if (!user) {
console.log("User does exist on the database.");
throw new UnauthorizedException();
}
await bcrypt.compare(password, user.password, function (err, result) {
if (!result) {
throw new UnauthorizedException();
}
const authJwtToken = await jwt.sign({ name: user.name, email: user.email, role: user.role }, "testSecreate");
const response = { name: user.name, email: user.email, role: user.role, token: authJwtToken }
console.log(response)
return response;
});
}
}
NOTE
The asynchronous method will be executed in parallel with your main program, so your console.log will be done before the callback function inside bcrypt.compare
. You will see always 'oops, it was false'.
Upvotes: 0