Skip to content

Commit a4a0482

Browse files
101577: Fixed ListableObjectComponentLoaderComponent not updating its @listableObjectComponent components ngOnChanges
1 parent 10d5f3d commit a4a0482

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ describe('ListableObjectComponentLoaderComponent', () => {
148148
(listableComponent as any).reloadedObject.emit(reloadedObject);
149149
tick();
150150

151-
expect((comp as any).instantiateComponent).toHaveBeenCalledWith(reloadedObject);
151+
expect((comp as any).instantiateComponent).toHaveBeenCalledWith(reloadedObject, undefined);
152152
}));
153153

154154
it('should re-emit it as a contentChange', fakeAsync(() => {

src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import { getListableObjectComponent } from './listable-object.decorator';
1919
import { GenericConstructor } from '../../../../core/shared/generic-constructor';
2020
import { ListableObjectDirective } from './listable-object.directive';
2121
import { CollectionElementLinkType } from '../../collection-element-link.type';
22-
import { hasValue, isNotEmpty } from '../../../empty.util';
23-
import { Subscription } from 'rxjs';
22+
import { hasValue, isNotEmpty, hasNoValue } from '../../../empty.util';
23+
import { Subscription, combineLatest, of as observableOf, Observable } from 'rxjs';
2424
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
2525
import { take } from 'rxjs/operators';
2626
import { ThemeService } from '../../../theme-support/theme.service';
@@ -147,8 +147,18 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges
147147
* Whenever the inputs change, update the inputs of the dynamic component
148148
*/
149149
ngOnChanges(changes: SimpleChanges): void {
150-
if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
151-
this.connectInputsAndOutputs();
150+
if (hasNoValue(this.compRef)) {
151+
// sometimes the component has not been initialized yet, so it first needs to be initialized
152+
// before being called again
153+
this.instantiateComponent(this.object, changes);
154+
} else {
155+
// if an input or output has changed
156+
if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
157+
this.connectInputsAndOutputs();
158+
if (this.compRef?.instance && 'ngOnChanges' in this.compRef.instance) {
159+
(this.compRef.instance as any).ngOnChanges(changes);
160+
}
161+
}
152162
}
153163
}
154164

@@ -158,7 +168,7 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges
158168
.forEach((subscription) => subscription.unsubscribe());
159169
}
160170

161-
private instantiateComponent(object) {
171+
private instantiateComponent(object: ListableObject, changes?: SimpleChanges): void {
162172

163173
this.initBadges();
164174

@@ -177,14 +187,21 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges
177187
[this.badges.nativeElement],
178188
]);
179189

180-
this.connectInputsAndOutputs();
190+
if (hasValue(changes)) {
191+
this.ngOnChanges(changes);
192+
} else {
193+
this.connectInputsAndOutputs();
194+
}
181195

182196
if ((this.compRef.instance as any).reloadedObject) {
183-
(this.compRef.instance as any).reloadedObject.pipe(take(1)).subscribe((reloadedObject: DSpaceObject) => {
197+
combineLatest([
198+
observableOf(changes),
199+
(this.compRef.instance as any).reloadedObject.pipe(take(1)) as Observable<DSpaceObject>,
200+
]).subscribe(([simpleChanges, reloadedObject]: [SimpleChanges, DSpaceObject]) => {
184201
if (reloadedObject) {
185202
this.compRef.destroy();
186203
this.object = reloadedObject;
187-
this.instantiateComponent(reloadedObject);
204+
this.instantiateComponent(reloadedObject, simpleChanges);
188205
this.contentChange.emit(reloadedObject);
189206
}
190207
});
@@ -220,7 +237,7 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges
220237
*/
221238
protected connectInputsAndOutputs(): void {
222239
if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
223-
this.inAndOutputNames.forEach((name: any) => {
240+
this.inAndOutputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => {
224241
this.compRef.instance[name] = this[name];
225242
});
226243
}

0 commit comments

Comments
 (0)