Rabbani_
Rabbani_

Reputation: 470

Nestjs not receiving data service to Controller

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

Answers (2)

Jay McDoniel
Jay McDoniel

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

user10057478
user10057478

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

Related Questions