store data in memory with nestjs

Advertisements

I am trying to persist some data in my nestjs server so I can then use that data in my client app through http requests.

I have created a products.service.ts file with the function getAllData() that fetch some data and creates a new array that is asigned to the variable products (wich is the data I’m trying to persist). This function is called when the app is initialized (I know this works becouse when I run the app the console.log(this.products) inside the function shows data.

This is my products.service.ts code:

import { Injectable } from '@nestjs/common';

@Injectable()
export class ProductsService {
  private products: any[] = [];

  getProducts(): any[] {
    //empty
    console.log(this.products); 
    return this.products;
  }

  async getAllProducts(): Promise<any[]> {
    const categories = await this.getProductsCategories();
    const productsPromises = categories.categories.map(async (category) => {
        const products = await this.getProductsByCategory(category.strCategory);
        const modifiedProducts = products.meals.map((product) => {
            ....
        });
        return modifiedProducts;
      });
      
      const products = await Promise.all(productsPromises);
      const flattenedProducts = products.flat();

      this.products = flattenedProducts;
      //shows data
      console.log(this.products) 
      
      return flattenedProducts;
    }

  async getProductsCategories(): Promise<any>{
    try{
      const apiURL = 'https://www.themealdb.com/api/json/v1/1/categories.php';
      const apiResponse = await fetch(apiURL);
      const categories = await apiResponse.json(); 

      return categories;
    }
    catch(e){
      throw new Error('Error while fetching products');
    }
  }
  async getProductsByCategory(category: string): Promise<any> {
    try {
      const apiURL = `https://www.themealdb.com/api/json/v1/1/filter.php?c=${category}`;
      const apiResponse = await fetch(apiURL);
      const products = await apiResponse.json();

      return products;
    } catch (e) {
      throw new Error('Error while fetching products by category');
    }
  }
}

The function getProducts() is called in my products.controller.ts file when an http request is done in the route ‘/products’ but the products array is empty:

import { Controller, Get, Param } from '@nestjs/common';
import { ProductsService } from './products.service';

@Controller('products')
export class ProductsController {
    constructor(private readonly ProductsService: ProductsService) {}

 @Get('/')
    async getAllProducts(): Promise<any[]> {
        const products = await this.ProductsService.getProducts();

        return products;
     }
 }

Any idea why the products variable is empty when I make the request ? It should have the data created with getAllProducts() as this function is called onModuleInit

UPDATE 1:

I’ll add the products.module.ts where I call getAllProducts() onModuleInit:

import { Module, OnModuleInit } from '@nestjs/common';
import { ProductsController } from './products.controller';
import { ProductsService } from './products.service';

@Module({
    controllers: [ProductsController],
    providers: [ProductsService],
})

export class ProductsModule implements OnModuleInit {
    constructor(private readonly productsService: ProductsService) {}
  
    async onModuleInit() {
      await this.productsService.getAllProducts();
    }
}

Then I import and use this module at app.module.ts file:

import { ProductsModule } from './products/products.module';
...

@Module({
  imports: [ProductsModule],
  controllers: [AppController, ProductsController],
  providers: [AppService, ProductsService],
})

export class AppModule {}

>Solution :

Don’t add the ProductsController and ProductsService to the AppModule. You essentially have two "versions" of the ProductsController and ProductsService being instantiated, and Nest is calling the one that didn’t run the onModuleInit from the ProductsModule. Remove them from the AppModule it and should all work.

Leave a ReplyCancel reply