Skip to content

Commit

Permalink
fix(accordion): don't fail when calling toggle() too early (#4506)
Browse files Browse the repository at this point in the history
Make sure to not fail when `QueryList` is `undefined`

#4505
  • Loading branch information
maxokorokov committed May 17, 2023
1 parent c524384 commit 08585a3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
13 changes: 13 additions & 0 deletions src/accordion/accordion.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,19 @@ describe('ngb-accordion directive', () => {
return { fixture, accordionDirective, nativeElement };
}

it(`ensure methods don't fail when called before view init`, inject(
[NgbAccordionConfig],
(config: NgbAccordionConfig) => {
const accordion = new NgbAccordionDirective(config);
accordion.toggle('one');
accordion.collapse('one');
accordion.expand('one');
accordion.expandAll();
accordion.collapseAll();
accordion.isExpanded('one');
},
));

it('should check if a panel with a given id is expanded', () => {
const html = `
<div ngbAccordion>
Expand Down
28 changes: 15 additions & 13 deletions src/accordion/accordion.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export class NgbAccordionItem implements AfterContentInit, OnDestroy {
host: { '[class.accordion]': 'true' },
})
export class NgbAccordionDirective {
@ContentChildren(NgbAccordionItem, { descendants: false }) private _items: QueryList<NgbAccordionItem>;
@ContentChildren(NgbAccordionItem, { descendants: false }) private _items?: QueryList<NgbAccordionItem>;
/**
* If `true`, accordion will be animated.
*/
Expand Down Expand Up @@ -372,7 +372,7 @@ export class NgbAccordionDirective {
* @param itemId The id of the item to expand.
*/
expand(itemId: string) {
const item = this._getItem(itemId)?.expand();
this._getItem(itemId)?.expand();
}

/**
Expand All @@ -381,14 +381,16 @@ export class NgbAccordionDirective {
* If `closeOthers` is `true` and all items are closed, it will open the first one. Otherwise, it will keep the opened one.
*/
expandAll() {
if (this.closeOthers) {
// we check if there is an item open and if it is not we can expand the first item
// (otherwise we toggle nothing)
if (!this._items.find((item) => !item.collapsed)) {
this._items.first.expand();
if (this._items) {
if (this.closeOthers) {
// we check if there is an item open and if it is not we can expand the first item
// (otherwise we toggle nothing)
if (!this._items.find((item) => !item.collapsed)) {
this._items.first.expand();
}
} else {
this._items.forEach((item) => item.expand());
}
} else {
this._items.forEach((item) => item.expand());
}
}

Expand All @@ -407,7 +409,7 @@ export class NgbAccordionDirective {
* Collapses all items.
*/
collapseAll() {
this._items.forEach((item) => item.collapse());
this._items?.forEach((item) => item.collapse());
}

/**
Expand All @@ -417,7 +419,7 @@ export class NgbAccordionDirective {
*
* @param itemId The id of the item to check.
*/
isExpanded(itemId: string): boolean {
isExpanded(itemId: string) {
const item = this._getItem(itemId);
return item ? !item.collapsed : false;
}
Expand Down Expand Up @@ -449,7 +451,7 @@ export class NgbAccordionDirective {
return true;
}

private _getItem(itemId: string) {
return this._items.find((item) => item.id === itemId);
private _getItem(itemId: string): NgbAccordionItem | undefined {
return this._items?.find((item) => item.id === itemId);
}
}

0 comments on commit 08585a3

Please sign in to comment.