EdwinU
EdwinU

Reputation: 85

is there a way to return data from mongoose? Typescript, NestJS

I am working with nestjs and mongoose. is there a correct way to return the data or simplify this code? especially let response = ....

pets.controller.ts

.
.

//getPets
@Get('read')
async getPets(@Req() _req: Request, @Res() _res: Response) {


    let response: HttpResponse = await this.petService.getAll()
        .then(result => {
            return {
                code: HttpStatus.OK,
                ok: true,
                message: result,
            }

        }).catch(err => {
            return {
                code: HttpStatus.INTERNAL_SERVER_ERROR,
                ok: true,
                message: err,
            }
        });

    return _res.status(response.code).json(response);
}

pets.service.ts

//READ ALL
async getAll(): Promise<PetInterface[]> {

    return await this.petsModel.find();
}

or some good practices that are used?

Upvotes: 1

Views: 998

Answers (2)

AlexZeDim
AlexZeDim

Reputation: 4352

Also, extending SPS answer about Mongo itself.

If you returning documents for API responses, you don't need the Mongoose document itself. A lean version of them will be fine and much less heavy. So add .lean() to your queries, like await this.petsModel.find().lean() (or pass it as a { query: option }). The interface type will be LeanDocument<Doctype> for a single document.

The second thing is: don't return all documents in one query. It's ok for study purposes, but not for production. Add limit to your query, make a pagination with limit and skip, or stream data via cursor().

Upvotes: 2

SPS
SPS

Reputation: 943

Here are some problems with the code

  1. Do not use await with then(). await wraps the statement in then().
  2. You don't need to write HTTP errors on your own. NestJS provides plenty of default ones.
  3. If you need to write your own errors, use exception filters to catch them and write your own logic for custom errors.
  4. Don't inject @Req and @Res everywhere. Make use of DTOs. It is a lifesaver.
  5. Always try to return the response in a DTO or an interface.
  6. Try to handle the errors where it is relevant. Not in controllers(not always)

How to do it in the NestJS Way :

pets.controller.ts

//getPets
@Get('read')
public async getPets() {
    return await this.petService.getAll();
}

pets.service.ts

//READ ALL
public async getAll(): Promise<PetResponseDTO[]> {
    try{
       const petsQueryResult = await this.petsModel.find();
        return PetResponseDTO.listOfPetsFromQueryResult(petsQueryResult);
        }catch (e){
         //Whatever you want to do with the error.
         //...
         //Imported from @nestjs/common
         throw new BadRequestException('<Reason>');
         // OR
         throw new InternalServerErrorException();
        }
}

pet.response.dto

export class PetResponseDTO{

 public static listOfPetsFromQueryResult(petsQueryResult:<query result type>[]): PetResponseDTO[]{
     const listOfAllPets = [];
     for(const pet of petsQueryResult){
      listOfAllPets.push(new PetResponseDTO(id,name,petType));
    }
   return listOfAllPets;
  }

 constructor(id:string,name:string,petType:string){
   this.id = id;
   this.petType = petType;
   this.name = name;
  }

 id: string;
 name: string;
 petType: string;
//....Whatever fields you want
}

Upvotes: 3

Related Questions