How to connect mongo with nestJs? - mongodb

If I config mongo with nest js its come like this,
my files like this,
app.module.ts
item.schema.ts
items.module.ts
items.service.ts

I use a forwardRef in the other modules where I declare the mongo models like this:
#Module({
imports: [
forwardRef(() => AppModule),
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])
]
})
Where AppModule my app.module is

Just remove the ItemsService from the AppModule and exports it on your ItemsModule, besides no need to define the ItemsController on the AppModule it's enough to be defined on the ItemsModule.
You may have a look about contollers and exports following this link https://docs.nestjs.com/modules

Related

Mongoose Error: Cannot read property 'length' of undefined in NestJs

I am using nests framework and versions of mongodb and mongoose are as specified below.
Please refer to the screenshot for error in detail.
versions
"mongodb": "4.0.0",
"mongoose": "5.5.12",
Error Screenshot
User Document Module
import { Module } from '#nestjs/common';
import { UserDocumentsService } from './user-documents.service';
import { UserDocumentsController } from './user-documents.controller';
import { MongooseModule } from '#nestjs/mongoose';
import { UserDocumentsSchema } from './schema/user-documents.schema';
#Module({
imports: [
// showing error on this line
MongooseModule.forFeature([
{ name: 'UserDocument', schema: UserDocumentsSchema },
]),
],
controllers: [UserDocumentsController],
providers: [UserDocumentsService],
})
export class UserDocumentsModule {}
App.module.ts
#Module({
imports: [
MongooseModule.forRootAsync({
imports: [SharedModule],
useFactory: async (configService: ConfigService) => ({
uri: configService.mongoDBName(),
useNewUrlParser: true,
useFindAndModify: false,
}),
inject: [ConfigService],
}),
UserDocumentsModule,
],
providers: [AppGateway],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
consumer.apply(contextMiddleware).forRoutes('*');
}
}
UPDATE
I think there is something wrong with the mongoose imports in the schema file. It says "could not find declaration for module 'mongoose'".
I tried removing and reinstalling mongoose and it's types. But now it shows new error.
I tried solutions mentioned in this post:
Node.js heap out of memory
But this also didn't work for me.
I'm using Mac-M1 with 8GB config.
UPDATE
The issue has been resolved now. The project is running on node v10.24.1 and I was using node v16.6.2.
After downgrading node version using NVM, this issue is gone.
You'll have to pull SharedModule import off MongooseModule.
Try this:
#Module({
imports: [
MongooseModule.forRootAsync({
useFactory: async (configService: ConfigService) => ({
uri: configService.mongoDBName(),
useNewUrlParser: true,
useFindAndModify: false,
}),
inject: [ConfigService],
}),
UserDocumentsModule,
SharedModule
],
providers: [AppGateway],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
consumer.apply(contextMiddleware).forRoutes('*');
}
}
It was because I was using a wrong version of node. The project was built on node v10.24.1 and I was using node v16.6.2.
After downgrading node version using NVM, I was able to fix this issue.

TypeError: rxjs_1.lastValueFrom is not a function

I am building an api using nestjs. After adding the typeorm and pg dependencies and adding the TypeOrmModule.forRoot({}) code in app.module.ts like shown below.
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CoffeesModule } from './coffees/coffees.module';
#Module({
imports: [CoffeesModule, TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'xxx',
database: 'postgres',
autoLoadEntities: true,
synchronize: true
})],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
I get an error TypeError: rxjs_1.lastValueFrom is not a function with but no error when I exclude TypeOrmModule.forRoot({}).
What could be the reason for the error ?
If you're using Nest v8, RxJS version 7 is used, which no longer has a toPromise() method for Observables, so Nest uses the lastValueFrom method instead. If you're receiving this error, you probably need to update your rxjs dependency to >7.
npm i rxjs#^7
yarn add rxjs#^7
pnpm i rxjs #^7
Pick your flavor of package manager and have at it.
In the last update of NestJS, when is used cli to initialization of project this error is throw.
The real answer
The issue is conflict with nest version.. anyone who see this - just make sure all your nestJs packages are of version 7 or 8 - don't mix them. especially those:
#nestjs/common
#nestjs/core
#nestjs/typeorm
from here: https://github.com/nestjs/nest/issues/7468#issuecomment-876174870
update "#nestjs/typeorm": "^7.1.5" in package.json and enter npm i and restart server

ConfigModule isn't working properly in nestjs

I am working on nestjs and mongoose recently. I put my MongoDB connection links on .env file. I have configured my nestjs application using ConfigModule. I followed the nestjs docs. But I have no idea why env variables are not working for me.
I have one extra module.ts file called content.module.ts in which I am connecting to mongodb. I have configured this ConfigModule in my app.module.ts and put it as global.
// app.module.ts
#Module({
imports: [
ConfigModule.forRoot({
envFilePath: './config/.env',
isGlobal: true,
}),
ContentModule, //another module
],
})
export class AppModule {}
// content.module.ts
#Module({
imports: [
MongooseModule.forRoot(process.env.CONTENT_DB_CONNECTION_STRING),
MongooseModule.forFeature([{ name: 'App', schema: AppSchema },]),
],
})
export class ContentModule {}
When I run my project using the debugger, I found that MongooseModule was first getting executed in the content.module.ts file, and then configModule was getting executed.
I even tried to configure the configModule in the content.module.ts file itself like below but no luck.
#Module({
imports: [
ConfigModule.forRoot({
envFilePath: '../../config/.env',
}),
MongooseModule.forRoot(process.env.CONTENT_DB_CONNECTION_STRING),
MongooseModule.forFeature([{ name: 'App', schema: AppSchema },]),
],
})
export class ContentModule {}
.env file
PORT=3000
CONTENT_DB_CONNECTION_STRING=mongodb://localhost:27017/content
project structure
I didn't get why mongoose dependencies are getting executed before the nestjs dependencies? And I also need help to fix this env variable.

Ionic 4 - Pipe could not be found

I have 2 pages to use a custom pipe. I have created a folder in src/app named pipes. And created a file pipes.module.ts
import { NgModule } from '#angular/core';
import { TranslatePipe } from './translate.pipe';
#NgModule({
declarations: [
TranslatePipe
],
imports: [],
exports: [
TranslatePipe
]
})
export class PipesModule {}
and im importing it from my first component module file
devices.module.ts
import { PipesModule } from '../pipes/pipes.module';
#NgModule({
imports: [
...
PipesModule
],
declarations: [DevicesPage, ]
})
export class DevicesPageModule {}
this component works well when i use pipe.
but i have another component too.
home.module.ts
import { PipesModule } from '../pipes/pipes.module'
#NgModule({
imports: [
PipesModule,
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild([
{
path: '',
component: HomePage
}
]),
ComponentsModule,
MatPaginatorModule,
],
declarations: [HomePage]
})
export class HomePageModule {}
im calling home page from devices page with a button. But i get error when i click the button.
pipes.module.ts;
import { NgModule } from '#angular/core';
//import custom pipes here
#NgModule({
declarations: [
TranslatePipe
],
imports: [],
exports: [
TranslatePipe
]
})
export class PipesModule {}
I faced with same issue in ionic-V4 app. I solved my issue like this. see this code you will know. I removed pipe from app.module.ts file.
Create a new pipe using the below command:
ionic g pipe translatePipe
Then import this pipe to home.module.ts file.
import { FirstCapsPipe } from '../first-caps.pipe';
Then include it in the declarations of the home.module.ts file.
declarations: [HomePage, FirstCapsPipe]
home.html
<h2>{{data|translatePipe}}</h2>
hope it help you :)
1) Firstly, create pipes folder in src/app folder (in app folder).
2) Second, on cmd "ionic generate pipe pipes/searchfilter" => this will generate two files in pipes.
3 Third, create file in pipes folder with name "pipes.module.ts"
and write below code to => "pipes.module.ts"
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { SearchfilterPipe } from './searchfilter.pipe'; //our pipe which we generate
#NgModule({
imports: [
CommonModule
],
declarations: [SearchfilterPipe],
exports: [SearchfilterPipe]
})
export class PipesModule { }
Now we have PipesModule we can generate more pipes and write them in pipesmodule. We will import only PipesModule instead of all pipes.
4) You do not have to import PipesModule in app.module.ts
5) Now go to page which you want to use pipe and open for example "anasayfa.module.ts"
and import "PipesModule" and write it in #ngModel imports(it will be created automatically)
Please be careful you will import PipesModule to something.MODULE.TS not something.page.ts
Ionic 4 Solution:
This is how I got custom pipe working in Ionic 4:
Created custom pipe in pipes folder in the app directory using:
ionic g pipe plural-singular
NOTE: You can create the pipe wherever you please in your project directory, although I recommend placing it in pipes directory for the sake of organization.
In the module of the page where I wanted to use this pipe, I imported the pipe and specified it under providers and declarations, like so:
all.module.ts
import {PluralSingularPipe} from '../../pipes/plural-singular.pipe';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
providers: [
PluralSingularPipe //---> Here
],
declarations: [PluralSingularPipe] //---> And here
})
Imported the pipe in the TS file of the page where I wanted to use the pipe, like so:
all.page.ts
import {PluralSingularPipe} from '../../pipes/plural-singular.pipe';
Declared the pipe in the constructor of the same page, like so:
all.page.ts
constructor(public pluralSingular: PluralSingularPipe) {}
Used it in my HTML file, like so:
all.page.html
{{ numberOfRecords | pluralSingular: 'coupon' : 'coupons' }}
That's it!
FOR THE CURIOUS: If it helps, here are my versions from package.json file:
"#ionic/angular": "^4.7.1",
"#angular/core": "~8.1.2",
I realized I forgot to import PipesModule for child components in homepage. Problem solved after i imported
save a lot of reading and experiments by just importing the pipe on every module that you need to use it in.
For example if you have a page called home and you want to use the pipe here, go to home.module.ts and import it there, add the pipe in declarations and in exports and you are done!
Now if you have multiple pipes create a module, you can even call it allmypipes.module.ts.
import all the relevant pipes into this module and add them to declarations and exports, then import this module to every page (page.module.ts) you want to use any of the pipes and you are done!

Getting Angular2 error 'No provider for Router! (RouterOutlet -> Router)'

I use Angular2 alpha39 and Babel to transpile the ES6 JS file. I'm not using typescript.
I created a component which displays correctly. I added a router-outlet to the template. When I run the app, I get the error message:
No provider for Router! (RouterOutlet -> Router)
The call stack is:
Here is the snippet of code:
template:
.... // Removed for brevity
<div class="contenttext">
<router-outlet></router-outlet>
</div>
.... // Removed for brevity
Component file:
import { Component, View, bootstrap, OnInit } from 'angular2/angular2';
import { RouteConfig, RouterOutlet, RouterLink } from 'angular2/router';
import 'reflect-metadata';
import 'winjs';
#Component({
selector: 'dashboard-app'
})
#View({
templateUrl: '../js/dashboard.html',
directives: [ ContentComponent, FamiliesComponent, RouterOutlet, RouterLink ]
})
#RouteConfig([
{ path: '/employees', component: EmployeesComponent, as: 'employees'}
])
class DashboardAppComponent implements OnInit {
constructor() {
}
onInit() {
WinJS.UI.processAll().done(function() {
var splitView = document.querySelector(".splitView").winControl;
new WinJS.UI._WinKeyboard(splitView.paneElement);
})
}
}
bootstrap(DashboardAppComponent);
you have to use:
ROUTER_BINDINGS in your bootstrap.
in your index.html.
if possible use state i.e as "employees" in capitalize i.r as "Employees". (in alpha 42 i have solve one problem this way).
i hope this will surely help you.
--UPDATE--
after the relese of alpha41:
ROUTER_BINDINGS has been changed with ROUTER_PROVIDERS .
Router Aliases should be in the camel case manner.
for the Router-outler and router-link you just have to import ROUTER_DIRECTIVES in your directives property in the component annotation.
Router-link expects the value to be an array of route names. for more info. refer here .
for more info regarding Routing you may refer to this tutorial here .
---Update2---
Now ( as of alpha-49) router is exported as ng.router.
(According to alpha-47 all life cycle hooks renamed as.)
onActivate, onReuse, onDeactivate, canReuse, canDeactivate
To :--
routerOnActivate,routerOnReuse,routerOnDeactivate,routerCanReuse,routerCanDeactivate
---Update3---
router-link is changed to routerLink
and routeconfig property changed to:
{path: '/abc', component: ABC, as: 'abc'}
to:
{path: '/xyz' , component: XYZ, name: 'xyz'}
--Update 4 --
UPDATE TO ANGULAR2 RC
There are alot of changes has been made in routing in angular2 after RC some of them points i am going to mention here may help someone :-
angular2/router has been changed with #angular/router
(also you can use old functionality of routing using import of #angular/router-deprecated but as of now we have to use #angular/router).
#RouteConfig has been changed with #Routes .
for example :-
#Routes([
{path: '/crisis-center', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent}
])
2.0.0-alpha.36 (2015-08-31)
routerInjectables was renamed to ROUTER_BINDINGS
2.0.0-alpha.41 (2015-10-13)
ROUTER_BINDINGS was renamed to ROUTER_PROVIDERS
USE ROUTER_PROVIDERS
ROUTER_PROVIDERS is used to simplify bootstrapping the router.
It includes:
RouterRegistry - the collection of registered routes
LocationStrategy = PathLocationStrategy - match by path
ROUTER_PROVIDERS provides 'sane' defaults and should be used unless you need to need a different route LocationStrategy.
Change:
bootstrap(DashboardAppComponent);
To:
bootstrap(DashboardAppComponent, [
ROUTER_PROVIDERS
]);
Sources:
angular/commit/ccfadb9
angular/pr#4654
2.0.0-alpha.38 (2015-10-03)
Route aliases need to be CamelCase (technically PascalCase)
Note: this was mentioned already in Pardeep's answer under #3
If you want to include a link to a route in your template via router-link you have to make sure the alias (ie the name property) of the route is PascalCase.
If you use plan to use router-link modify the route to:
{ path: '/employees', component: EmployeesComponent, name: 'Employees'}
Then you can add the link in your template with:
<a [router-link]="['/Employees']">Employees Link</a>
RouterLink dynamically inserts a href that matches the route path.
Note: Reading the issue/pr it appears this change was made to prevent users from confusing the <route-link> binding with the route url
Sources:
https://groups.google.com/d/msg/angular/IF3_UCJt340/6AgSF76XAwAJ
angular/issues#4318
angular/pr#4643
Tip:
If you want to simplify your view directives use ROUTER_DIRECTIVES
It includes:
RouterLink
RouterOutlet
Update:
In the near future, RouterOutlet/<router-outlet> will be renamed to RouterViewport/<router-viewport>
Source:
angular/issues#4679
Update 2:
The RouteConfig property as has been renamed to name
Source:
angular/commit/7d83959
Answer on Dec 23rd 2016 (Angular v2.4.1, Router v3.4.1 - should work for any NG v2.x.x + Router v3.x.x)
I just migrated three of our apps from the Webpack Starter Seed to Angular CLI (v1.0.0-beta.24) and hit this issue.
Only a tiny fraction of what's on the NG 2 massive router doc page is required:
An app-routing.module.ts file (typically in src/app/ folder) looking like this sample:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
const appRoutes: Routes = [
{ path: '', component: YourHomePageComponent },
{ path: 'next-page', component: NextComponent }
];
#NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule {}
Import AppRoutingModule into your main module (typically src/app/app.module.ts):
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule // <--- The import you need to add
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Ensure you have <router-outlet></router-outlet> somewhere in your main html (often src/app/app.component.html) as this is where router content is injected.
Make sure you have router defined and declared in AppModule.
Example (look everywhere where routing is mentioned, ignore the rest):
app.routing.ts
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { HeroesComponent } from './heroes.component';
import {DashboardComponent} from './dashboard.component';
import {HeroDetailComponent} from './hero-detail.component';
const appRoutes: Routes = [
{
path: 'heroes',
component: HeroesComponent
},
{
path: 'dashboard',
component: DashboardComponent
},
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
{
path: 'detail/:id',
component: HeroDetailComponent
},
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
and app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
import { routing } from './app.routing';
import './rxjs-extensions';
import {HeroSearchComponent} from './hero-search.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
routing
],
declarations: [
AppComponent,
DashboardComponent,
HeroDetailComponent,
HeroesComponent,
HeroSearchComponent
],
providers: [
HeroService,
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
This can save someone an hour:
You get this error if you don't even use routing (for example temporary, maybe you don't import routing config and router-outlet is commented out) BUT you are using Router or ActivatedRoute in some component constructor via dependency injection, like this:
#Component({...}})
export class SomeComponent {
constructor(private _router: Router, private _route: ActivatedRoute) {
//may be you are not using _route/_route at the moment at all!
}
...
}
You cant user Dependency Injection for Router if you dont define any routs!
To define route user something similar to following codes:
const loginRoutes: Routes = [
{path: 'foo/bar/baz', component: 'MyRootComponent'}
];
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
JsonpModule,
RouterModule.forRoot(loginRoutes)
],
providers: [],
declarations: [
MyLoginComponent
],
bootstrap: [
MyLoginComponent
]
})
export class MyLoginModule
{
}