APP_INITIALIZER failing test cases - javascript

I am using APP_INITIALIZER to make some API calls, everything is working fine but adding
{ provide: APP_INITIALIZER, useFactory: MyProviderFactory, deps: [MyService], multi: true }
in app.module.ts failing my test cases.
Here is my app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { RouterModule } from '#angular/router';
import { HttpClientModule } from '#angular/common/http';
import { LayoutModule } from '#angular/cdk/layout';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
// tslint:disable-next-line:max-line-length
import { MyService } from './services/my-provider.service';
export function MyProviderFactory(provider: MyService) {
return () => provider.getdata();
}
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule,
BrowserAnimationsModule,
HttpClientModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: AppComponent }
])
],
providers: [ MyService,
{ provide: APP_INITIALIZER, useFactory: MyProviderFactory, deps: [MyService], multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is the error
"message": "An error was thrown in afterAll\nFailed: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
Also how to test APP_INITIALIZER in the app.
Any help would be appreciated.

As your error says, your factory is not returning a stream (observable, promise, array or iterable). Instead, you are returning a function.
Assuming your MyService.getdata() returns one of those, you can just return it return provider.getdata().

Related

Component can't find imported element anymore when being shared

What I did so far:
I imported a component into the share module because I want to use it on 2 different Modules. Now when I'm recompiling the app it says that jodit-editor which is used by the shared component is not a known element. (worked completely normal before shared the component)
This is how the shared Component look like:
import { Component, forwardRef, Input, OnInit, ViewChild } from '#angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '#angular/forms';
import { JoditAngularComponent } from 'jodit-angular';
import { NGXLogger } from 'ngx-logger';
import { Widget } from 'src/app/models/widget';
import { IFile } from 'src/interfaces';
import { WysiwygTemplates } from './wysiwyg.templates';
import { FileService } from 'src/app/services/file.service';
import { StorageService } from 'src/app/services/storage.service';
#Component({
selector: 'app-wysiwyg',
templateUrl: './wysiwyg.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => WysiwygComponent),
}
],
})
This is how the share module look like:
import { CommonModule, registerLocaleData } from '#angular/common';
import { NgModule } from '#angular/core';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppButtonComponent } from 'src/app/utils/app-button/app-button.component';
import { ConfirmDialogComponent } from 'src/app/utils/confirm-dialog/confirm-dialog.component';
import { MatDialogModule } from '#angular/material/dialog';
import { FormErrorComponent } from 'src/app/utils/form-error/form-error.component';
import { HttpClient } from '#angular/common/http';
import { TranslateHttpLoader } from '#ngx-translate/http-loader';
import { TranslateModule, TranslateLoader, TranslateService } from '#ngx-translate/core';
import localeDe from '#angular/common/locales/de';
import { DragDropDirectiveModule } from './directives/filedrag-drop.directive';
import { DragDropModule } from '#angular/cdk/drag-drop';
import { WysiwygComponent } from 'src/app/utils/inputs/wysiwyg/wysiwyg.component';
registerLocaleData(localeDe);
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, '../i18n/', '.json');
}
#NgModule({
imports: [
DragDropDirectiveModule,
CommonModule,
MatDialogModule,
NgbModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
isolate: false
}),
],
declarations: [
WysiwygComponent,
AppButtonComponent,
ConfirmDialogComponent,
FormErrorComponent
],
exports: [
WysiwygComponent,
DragDropDirectiveModule,
AppButtonComponent,
ConfirmDialogComponent,
FormErrorComponent,
MatDialogModule,
CommonModule,
FormsModule,
ReactiveFormsModule,
NgbModule,
TranslateModule,
DragDropModule
],
providers: [TranslateService]
})
export class SharedModule {}
When recompiling I getting this error:
The JoditAngularModule should be added to the imports of the shared module for your shared component to 'know' the element 'jodit-editor'.
This is the import statement.
import { JoditAngularModule } from 'jodit-angular';
Add it to the imports of shared module
imports:
[
// Other imports ,
JoditAngularModule
]
Hope this helps. Let me know if it works!

Browsermodule error for NgxDatetimeRangePickerModule

Hi my application was working fine till i added NgxDatetimeRangePickerModule, Once i added it in my shared module , I am getting BrowserModule has already been loaded error. Borwser module is present in only app.module and not in any module. What might be the issue.
Error :
vendor.js:77185 ERROR Error: Uncaught (in promise): Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
App.module.ts
import { NgModule, ApplicationModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { NgHttpLoaderModule } from 'ng-http-loader';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// 3rd party module
import { NgxDatetimeRangePickerModule } from 'ngx-datetime-range-picker';
// import { Cardscomponent } from './cards/cards.component';
import { NotificationToastComponent } from './_shared/notification-toast/notification-toast.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './_services/auth.guard';
import { AuthInterceptor } from './_services/auth.interceptor';
import { ErrorInterceptor } from './_services/error.interceptor';
import { SharedModule } from './_shared/shared.module';
#NgModule({
declarations: [
AppComponent,
NotificationToastComponent,
LoginComponent,
],
imports: [
SharedModule,
BrowserModule,
BrowserAnimationsModule,
ApplicationModule,
FormsModule,
ReactiveFormsModule,
AppRoutingModule,
HttpClientModule,
NgHttpLoaderModule.forRoot(),
NgbModule,
],
providers: [
AuthGuard,
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
],
entryComponents: [
NotificationToastComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
My Shared Module:
import { NgModule } from '#angular/core';
import { FilterDataPipe } from '../_pipes/filter-data.pipe';
import { AngularMaterialModule } from '../angular-material.module';
import { CommonModule } from '#angular/common';
import { AngularKendoModule } from '../angular-kendo.module';
import { NgxDatetimeRangePickerModule } from 'ngx-datetime-range-picker';
import { MustMatchDirective } from '../_helpers/must-match.directive';
#NgModule({
imports:[
CommonModule,
AngularMaterialModule,
AngularKendoModule,
],
declarations: [
FilterDataPipe,
MustMatchDirective
],
exports: [
CommonModule,
FilterDataPipe,
AngularMaterialModule,
MustMatchDirective,AngularKendoModule,
NgxDatetimeRangePickerModule
]
})
export class SharedModule {}
My child Module:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { Cardscomponent } from './cards.component';
import { SharedModule } from '../_shared/shared.module';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { CardsRoutingModule } from './cards-routing.module';
import { CardDetailsComponent } from './card-details/card-details.component';
import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown';
#NgModule({
imports: [
CommonModule,
SharedModule,
FormsModule,
ReactiveFormsModule,
CardsRoutingModule,
NgbModule,
NgMultiSelectDropDownModule.forRoot(),
],
declarations: [Cardscomponent,CardDetailsComponent]
})
export class CardsModule { }
Remove NgxDatetimeRangePickerModule from app.module move it to shared module.
In shared.module import NgxDatetimeRangePickerModule.forRoot() inside import section.
Thanks
Rahul Tokase

Uncaught (in promise): Error: Cannot match any routes (Angular8)

I maked my angular-app. All good works. But for deploy to server I getting error:
Uncaught (in promise): Error: Cannot match any routes. URL Segment:
'myUrl/app.aspx'
After build prod my app doesn't work either (I set base href and all files load, but I getting warning Unhandled Navigation Error).
I make difficult routing for my app.
I using submodules for routing. And I think the problem related with APP_BASE_HREF or wrong routing for my app/submodules.
My example:
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from "#angular/common/http";
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { NbThemeModule, NbLayoutModule, NbSidebarModule, NbButtonModule, NbTabsetModule, NbCardModule } from '#nebular/theme';
import { NbEvaIconsModule } from '#nebular/eva-icons';
import { AppRoutingModule } from './app-routing.module';
import { RouterModule } from '#angular/router';
import { MainModule } from './components/main/main.module';
import { AddModule } from './components/add/add.module';
import { APP_BASE_HREF } from '#angular/common';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
BrowserAnimationsModule,
NbThemeModule.forRoot({ name: 'default' }),
NbLayoutModule,
NbEvaIconsModule,
NbSidebarModule.forRoot(),
NbButtonModule,
NbTabsetModule,
NbCardModule,
AppRoutingModule,
MainModule,
AddModule,
HttpClientModule,
],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }
I don't have providers: [{ provide: APP_BASE_HREF, useValue: '/' }] and all good works. But for deploy I geted error message:
Please provide a value for the APP_BASE_HREF token or add a base
element to the document.
I add APP_BASE_HREF and error disappeared.
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
const routes: Routes = [
{
path: '',
loadChildren: './components/main/main.module#MainModule'
},
{
path: 'event',
loadChildren: './components/event/event.module#EventModule'
},
{
path: 'add',
loadChildren: './components/add/add.module#AddModule'
},
{
path: 'archive',
loadChildren: './components/archive/archive.module#ArchiveModule'
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule { }
main-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { ViewEventsComponent } from './view-events/view-events.component';
const routes: Routes = [
{
path: '',
component: ViewEventsComponent,
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class MainRoutingModule { }
event-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { EventPageComponent } from './event-page/event-page.component';
const routes: Routes = [
{
path: ':id',
component: EventPageComponent,
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class EventRoutingModule { }
And I noticed:
after build app - generated files of module: archive and event, but don't generated file for main-module.
I solved this problem with fixed in app-routing.module.ts. A added { useHash: true }:
#NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule],
})

Angular 8 basic interceptor not called on page loading

I'm in the process of adding an interceptor to my angular 8 project. To make add bearer token. Unfortunately the interceptor does not seem to be called. My code:
I already:
Added HttpClientModule, HTTP_INTERCEPTORS and HttpConfigInterceptor imports in app.module.ts file.
Added HttpClientModule in imports section after BrowserModule.
Added { provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true } in providers section.
app.module.ts file:
import { NgModule } from '#angular/core';
import { BrowserModule, Title } from '#angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http';
import { HttpConfigInterceptor } from './httpconfig.interceptor';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { HomeComponent } from './home/home.component';
import { PrivacyPolicyComponent } from './privacy-policy/privacy-policy.component';
import { TermsOfUseComponent } from './terms-of-use/terms-of-use.component';
import { SnippetsComponent } from './snippets/snippets.component';
import { SnippetComponent } from './snippet/snippet.component';
import { NotFoundComponent } from './not-found/not-found.component';
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
HeaderComponent,
FooterComponent,
HomeComponent,
PrivacyPolicyComponent,
TermsOfUseComponent,
SnippetsComponent,
SnippetComponent,
NotFoundComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [
Title,
{ provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
My interceptor file:
import { Injectable } from '#angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable()
export class HttpConfigInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(request);
return next.handle(request);
}
}
I want just the console.log works.
Thks ^^.

Getting 'ngbCollapse' since it isn't a known property of 'div'. error after moving components into sub module

Error
compiler.js:215 Uncaught Error: Template parse errors:
Can't bind to 'ngbCollapse' since it isn't a known property of 'div'. ("][ngbCollapse]="isHidden">
I have a NavbarComponent and a FooterComponent that I want to move into the SharedModule, to keep the root app.module cleaner.
app.module
import { AdminComponent } from './admin/admin.component';
// import { NavbarComponent } from './navbar/navbar.component';
// import { FooterComponent } from './footer/footer.component';
// Modules
import { DashboardModule } from './dashboard/dashboard.module';
import { HomeModule } from './home/home.module';
#NgModule({
declarations: [
AppComponent,
LoginComponent,
RegisterComponent,
PasswordResetComponent,
ResetPasswordComponent,
AdminComponent,
// NavbarComponent,
// FooterComponent,
share.module
However, once I moved those components into here, and update their paths correctly ./ -> ../ the app breaks.
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { NavbarComponent } from '../navbar/navbar.component';
import { FooterComponent } from '../footer/footer.component';
import { TermsComponent } from './terms.component';
import { PageNotFoundComponent } from './not-found.component';
import { PrivacyPolicyComponent } from './privacy-policy.component';
#NgModule({
imports: [
CommonModule
],
declarations: [
NavbarComponent,
FooterComponent,
TermsComponent,
PageNotFoundComponent,
PrivacyPolicyComponent
]
})
export class SharedModule { }
navbar.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../auth.service';
import { environment } from '../../environments/environment';
#Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit {
isHidden = true;
oauthUrl = this.authService.generateOauthUrl();
constructor(public authService: AuthService) { }
ngOnInit() {
}
logout() {
sessionStorage.clear();
}
}
Then a couple of lines with the [ngbCollapse] in navbar.component.html
<div *ngIf="!authService.isLoggedIn()" class="collapse navbar-collapse" id="navbarSupportedContent" [ngbCollapse]="isHidden">
I think this has something to do with the relative paths, any ideas?
To use ng-bootstrap components and directives in Angular templates, you need to import the NgbModule. In your case, you should import it in the SharedModule. Also, in order to use the shared components in other parts of the application, you should export them from the SharedModule and import the SharedModule in the modules when the components are to be used.
shared.module.ts
...
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
#NgModule({
imports: [
CommonModule,
NgbModule
],
declarations: [
NavbarComponent,
FooterComponent,
TermsComponent,
PageNotFoundComponent,
PrivacyPolicyComponent
],
exports: [
NavbarComponent,
FooterComponent,
TermsComponent,
PageNotFoundComponent,
PrivacyPolicyComponent
]
})
export class SharedModule { }
app.module.ts
import { SharedModule } from './shared/shared.module';
...
#NgModule({
imports: [
SharedModule,
...
],
...
})
Note: if you want to use ng-bootstrap components and directives in templates outside of the SharedModule, you should add NgbModule to the exports of the SharedModule.
To work with ng-bootsrap you should add this dependency first :
ng add #ng-bootstrap/ng-bootstrap
source: https://ng-bootstrap.github.io/#/home
then imporst the module as follows :
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
#NgModule({
imports: [
CommonModule,
NgbModule
],
...

Categories

Resources