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:
NgxMasonryModulein the module of which I'm using it in. In your case that should be the module in whichnote.componentis declarednote.componentin) 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)
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