I'm trying to import the module ngx-masonry
in my JHipster
app (angluar app).
I run
npm install ngx-masonry masonry-layout --save
Then imported the module inside app.module.ts
import { NgModule, LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import locale from '@angular/common/locales/en';
import { BrowserModule, Title } from '@angular/platform-browser';
import { ServiceWorkerModule } from '@angular/service-worker';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { TranslateModule, TranslateService, TranslateLoader, MissingTranslationHandler } from '@ngx-translate/core';
import { NgxWebstorageModule, SessionStorageService } from 'ngx-webstorage';
import * as dayjs from 'dayjs';
import { NgbDateAdapter, NgbDatepickerConfig } from '@ng-bootstrap/ng-bootstrap';
import { ApplicationConfigService } from 'app/core/config/application-config.service';
import './config/dayjs';
import { SharedModule } from 'app/shared/shared.module';
import { AppRoutingModule } from './app-routing.module';
import { HomeModule } from './home/home.module';
import { EntityRoutingModule } from './entities/entity-routing.module';
// jhipster-needle-angular-add-module-import JHipster will add new module here
import { NgbDateDayjsAdapter } from './config/datepicker-adapter';
import { fontAwesomeIcons } from './config/font-awesome-icons';
import { httpInterceptorProviders } from 'app/core/interceptor/index';
import { translatePartialLoader, missingTranslationHandler } from './config/translation.config';
import { MainComponent } from './layouts/main/main.component';
import { NavbarComponent } from './layouts/navbar/navbar.component';
import { FooterComponent } from './layouts/footer/footer.component';
import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
import { ErrorComponent } from './layouts/error/error.component';
import 'jquery/dist/jquery.js';
import '@angular/animations';
import { NgxMasonryModule } from 'ngx-masonry';
@NgModule({
imports: [
NgxMasonryModule,
BrowserModule,
SharedModule,
HomeModule,
// jhipster-needle-angular-add-module JHipster will add new module here
EntityRoutingModule,
AppRoutingModule,
// Set this to true to enable service worker (PWA)
ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
HttpClientModule,
NgxWebstorageModule.forRoot({ prefix: 'jhi', separator: '-', caseSensitive: true }),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translatePartialLoader,
deps: [HttpClient],
},
missingTranslationHandler: {
provide: MissingTranslationHandler,
useFactory: missingTranslationHandler,
},
}),
],
providers: [
Title,
{ provide: LOCALE_ID, useValue: 'en' },
{ provide: NgbDateAdapter, useClass: NgbDateDayjsAdapter },
httpInterceptorProviders,
],
declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
bootstrap: [MainComponent],
})
export class AppModule {
constructor(
applicationConfigService: ApplicationConfigService,
iconLibrary: FaIconLibrary,
dpConfig: NgbDatepickerConfig,
translateService: TranslateService,
sessionStorageService: SessionStorageService
) {
applicationConfigService.setEndpointPrefix(SERVER_API_URL);
registerLocaleData(locale);
iconLibrary.addIcons(...fontAwesomeIcons);
dpConfig.minDate = { year: dayjs().subtract(100, 'year').year(), month: 1, day: 1 };
translateService.setDefaultLang('en');
// if user have changed language and navigates away from the application and back to the application then use previously choosed language
const langKey = sessionStorageService.retrieve('locale') ?? 'en';
translateService.use(langKey);
}
}
Then I used the component inside note.component.html
file:
...Other html code...
<ngx-masonry>
<div class="grid" ngxMasonryItem >
<div class="grid-item card-selectable" *ngFor="let note of notes; trackBy: trackId">
<div [routerLink]="['/note', note.id, 'edit']">
<h5>{{note.title}}</h5>
</div>
</div>
</div>
</div>
</ngx-masonry>
...Other html code...
I also tried importing the module directly inside my note.component.ts
:
import { Component, OnInit } from '@angular/core';
import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { INote } from '../note.model';
import { ASC, DESC, ITEMS_PER_PAGE } from 'app/config/pagination.constants';
import { NoteService } from '../service/note.service';
import { NoteDeleteDialogComponent } from '../delete/note-delete-dialog.component';
import { ParseLinks } from 'app/core/util/parse-links.service';
import { NgxMasonryModule } from 'ngx-masonry';
@Component({
selector: 'jhi-note',
templateUrl: './note.component.html',
})
export class NoteComponent implements OnInit {
notes: INote[];
isLoading = false;
itemsPerPage: number;
links: { [key: string]: number };
page: number;
predicate: string;
ascending: boolean;
currentSearch: string;
constructor(
protected noteService: NoteService,
protected modalService: NgbModal,
protected parseLinks: ParseLinks,
protected activatedRoute: ActivatedRoute
) {
this.notes = [];
this.itemsPerPage = ITEMS_PER_PAGE;
this.page = 0;
this.links = {
last: 0,
};
this.predicate = 'id';
this.ascending = true;
this.currentSearch = this.activatedRoute.snapshot.queryParams['search'] ?? '';
}
loadAll(): void {
this.isLoading = true;
if (this.currentSearch) {
this.noteService
.search({
query: this.currentSearch,
page: this.page,
size: this.itemsPerPage,
sort: this.sort(),
})
.subscribe(
(res: HttpResponse<INote[]>) => {
this.isLoading = false;
this.paginateNotes(res.body, res.headers);
},
() => {
this.isLoading = false;
}
);
return;
}
this.noteService
.query({
page: this.page,
size: this.itemsPerPage,
sort: this.sort(),
})
.subscribe(
(res: HttpResponse<INote[]>) => {
this.isLoading = false;
this.paginateNotes(res.body, res.headers);
},
() => {
this.isLoading = false;
}
);
}
reset(): void {
this.page = 0;
this.notes = [];
this.loadAll();
}
loadPage(page: number): void {
this.page = page;
this.loadAll();
}
search(query: string): void {
this.notes = [];
this.links = {
last: 0,
};
this.page = 0;
if (query && ['hashcode', 'title', 'textContent', 'color'].includes(this.predicate)) {
this.predicate = 'id';
this.ascending = true;
}
this.currentSearch = query;
this.loadAll();
}
ngOnInit(): void {
this.loadAll();
}
trackId(index: number, item: INote): number {
return item.id!;
}
delete(note: INote): void {
const modalRef = this.modalService.open(NoteDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
modalRef.componentInstance.note = note;
// unsubscribe not needed because closed completes on modal close
modalRef.closed.subscribe(reason => {
if (reason === 'deleted') {
this.reset();
}
});
}
createTestNotes(): void {
this.noteService.createTestNotes().subscribe(() => {this.reset()});
}
deleteAllNotes(): void {
this.noteService.deleteAllNotes().subscribe(() => {this.reset()});
}
protected sort(): string[] {
const result = [this.predicate + ',' + (this.ascending ? ASC : DESC)];
if (this.predicate !== 'id') {
result.push('id');
}
return result;
}
protected paginateNotes(data: INote[] | null, headers: HttpHeaders): void {
this.links = this.parseLinks.parse(headers.get('link') ?? '');
if (data) {
for (const d of data) {
this.notes.push(d);
}
}
}
}
But keep getting this error:
2021-10-15T09:40:50.710+0200 [ERROR] [system.err] Error: src/main/webapp/app/entities/note/list/note.component.html:73:7 - error NG8001: 'ngx-masonry' is not a known element:
2021-10-15T09:40:50.710+0200 [ERROR] [system.err] 1. If 'ngx-masonry' is an Angular component, then verify that it is part of this module.
2021-10-15T09:40:50.710+0200 [ERROR] [system.err] 2. If 'ngx-masonry' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
2021-10-15T09:40:50.711+0200 [ERROR] [system.err]
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] 73 <ngx-masonry>
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] ~~~~~~~~~~~~~
2021-10-15T09:40:50.711+0200 [ERROR] [system.err]
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] src/main/webapp/app/entities/note/list/note.component.ts:17:16
2021-10-15T09:40:50.711+0200 [ERROR] [system.err] 17 templateUrl: './note.component.html',
2021-10-15T09:40:50.712+0200 [ERROR] [system.err] ~~~~~~~~~~~~~~~~~~~~~~~
2021-10-15T09:40:50.712+0200 [ERROR] [system.err] Error occurs in the template of component NoteComponent.
My package.json includes:
"jquery": "^3.6.0",
"masonry-layout": "^4.2.2",
"ngx-infinite-scroll": "10.0.1",
"ngx-masonry": "^12.0.0",
"@types/jquery": "3.5.7",
"@types/masonry-layout": "4.2.4",
Already tried stopping the server, npm, restarting the IDE.
I just happened to run into a similar problem on my application. I actually fixed it by:
NgxMasonryModule
in the module of which I'm using it in. In your case that should be the module in which note.component
is declarednote.component
in) is important as a module in every parent module above. In my case I didn't import the module I'm using the package in as a module, but as a component.Resulting in:
note.module (which is the module in which note.component is declared)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NoteComponent } from './content-grid.component';
import { NgxMasonryModule } from 'ngx-masonry';
@NgModule({
declarations: [
NoteComponent
],
imports: [
CommonModule,
NgxMasonryModule
]
})
export class NoteModule {
}
In case you use NoteModule in another module, make sure that both NoteModule as that other module get imported as modules, and not as components.
app.module
...
@NgModule({
declarations: [
...
],
imports: [
NoteModule
],
...