-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Closed
Labels
troubleshootingThis issue is not reporting an issue, but just asking for helpThis issue is not reporting an issue, but just asking for help
Description
What are you trying to do?
I'm trying to make a custom Angular Material multiSelect filterable component, such as this one :
I made a multi-select-search.component with this code :
export interface MultiSelectSearchOption {
label: string;
value: any;
}
export interface MultiSelectOverlayData {
options: MultiSelectSearchOption[];
}
export const MULTI_SELECT_OVERLAY_DATA = new InjectionToken<
MultiSelectOverlayData
>('MULTI_SELECT_OVERLAY_DATA');
//TEXT INPUT COMPONENTS
@Component({
selector: 'multiSelectSearch',
templateUrl: 'multiSelectSearch.component.html',
styleUrls: ['./multiSelectSearch.component.scss'],
})
export class MultiSelectSearchComponent implements AfterViewInit {
@Input() list: any[] = [];
@Input() selection: any;
/**
* @param filterKey
* @description the key of the object to filter out with the text input
*/
@Input() filterKey: string;
/**
* @param labelKey
* @description the key of the object to be used as label of option
*/
@Input() labelKey: string;
@Input() placeholder: string;
@Output() valueChange = new EventEmitter<any[]>();
@ViewChild('input', { static: false }) inputViewRef: ElementRef;
public search = new FormControl('');
private listOptions: MultiSelectSearchOption[] = [];
private overlayRef: OverlayRef;
constructor(private overlay: Overlay) {}
ngAfterViewInit() {
if (!this.list.length || !this.labelKey || !this.filterKey) {
console.error(
'Component usage require input of list, labelKey, filterKey component'
);
throw new Error();
} else {
this.search.valueChanges
.pipe(debounceTime(1000))
.subscribe(search => {
this.listOptions = (!search.length
? this.list
: this.list.filter(e =>
e[this.filterKey]
.toString()
.toUpperCase()
.startsWith(search.toUpperCase())
)
).map(
(e: any): MultiSelectSearchOption => ({
label: e[this.labelKey],
value: e,
})
);
const tokens = new WeakMap();
tokens.set(MULTI_SELECT_OVERLAY_DATA, {
options: this.listOptions,
});
this.overlayRef = this.overlay.create({
hasBackdrop: false,
minWidth: '10vw',
minHeight: '10vh',
positionStrategy: this.overlay
.position()
.flexibleConnectedTo(this.inputViewRef)
.withPositions([
{
offsetX: 0,
offsetY: 0,
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'top',
panelClass: [],
weight: 1,
},
]),
});
const multiSelectPortal = new ComponentPortal(
MultiSelectOverlayComponent,
null,
tokens
);
this.overlayRef.attach(multiSelectPortal);
});
}
}
}
// OVERLAY COMPONENT
@Component({
selector: 'multi-select-overlay',
template: `
<mat-card>
<mat-selection-list #list>
<mat-list-option
*ngFor="let option of listOptions"
[value]="option.value"
>{{ option.label }}</mat-list-option
>
</mat-selection-list>
</mat-card>
`,
})
export class MultiSelectOverlayComponent implements AfterViewInit {
@ViewChild('list', { static: false }) list: MatSelectionList;
public get listOptions() {
return this.data.options as MultiSelectSearchOption[];
}
constructor(
@Inject(MULTI_SELECT_OVERLAY_DATA)
private data: MultiSelectOverlayData
) {
console.log('data', data);
}
ngAfterViewInit() {
this.list.selectionChange.pipe(
//emit value
tap(x => console.log(x))
);
}
}
Everything seems to be working fine, but when i try to iterate over my data.options
element, i get the following error :
What troubleshooting steps have you tried?
I put a console.log
of the data
object passed, i can see that it is indeed an Array :
What are you seeing that does not match your expectations?
I don't understand why the component created by the ComponentPortal fail to use ngFor on an Array.?
Reproduction
We can only help if we can reproduce the problem ourselves.
Use StackBlitz to demonstrate what you are trying to do:
Full error and code here :
https://components-issue-55qrra.stackblitz.io/
Steps to reproduce:
- Use stackblitz to reproduce error
Environment
- Angular: 8.1.1
- CDK/Material: 8.0.2
- Browser(s): Chrome
- Operating System Windows,
Metadata
Metadata
Assignees
Labels
troubleshootingThis issue is not reporting an issue, but just asking for helpThis issue is not reporting an issue, but just asking for help