My code is the following in my component, I defined this:
public outputFormats = ["pdf", "png32", "png8", "jpg", "gif", "eps", "svg"];
In my template:
<div ngbDropdownMenu aria-labelledby="polylineStyleDropdown">
<button *ngFor="let format of outputFormats"
(click)="onOutputFormatChanged(format)">{{format}}
</button>
</div>
But I get the following error on init.
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
at NgForOf.ngDoCheck (common.js:3323:1)
at callHook (core.js:2536:1)
at callHooks (core.js:2495:1)
at executeInitAndCheckHooks (core.js:2446:1)
at selectIndexInternal (core.js:8447:1)
at Module.ɵɵadvance (core.js:8430:1)
at PrintComponent_Template (print.component.html:41:48)
at executeTemplate (core.js:9598:1)
at refreshView (core.js:9464:1)
at refreshComponent (core.js:10635:1)
defaultErrorLogger @ core.js:6479
handleError @ core.js:6527
(anonymous) @ core.js:29723
invoke @ zone.js:372
run @ zone.js:134
runOutsideAngular @ core.js:28604
tick @ core.js:29723
(anonymous) @ core.js:29571
invoke @ zone.js:372
onInvoke @ core.js:28705
invoke @ zone.js:371
run @ zone.js:134
run @ core.js:28559
next @ core.js:29570
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:25968
checkStable @ core.js:28627
onLeave @ core.js:28755
onInvokeTask @ core.js:28699
invokeTask @ zone.js:405
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1600
globalZoneAwareCallback @ zone.js:1626
When I did console.log(typeof this.outputFormats)
, it returns object. I tried to convert it to array using Array.from(this.outputFormats)
, Object.values(this.outputFormats)
but the result is still the same, it is output is still an object.
Versions: Angular Cli 12.1.4 TypeScript 4.3.5
Solutions that didn't work for me:
https://github.com/angular/angular/issues/6392
Angular error : Cannot find a differ supporting object '[object Object]'
Angular: Cannot find a differ supporting object '[object Object]'
CodePudding user response:
I've got modified a version of the documentation example to use what you've shared and it's working at https://stackblitz.com/edit/angular-3pnr1l with the TS/Angular versions you specified. It's ng-bootstrap 11.0 for what it's worth, but you hadn't specified that.
One difference in the implementation is the use of <Button ngbDropdownItem
.
# dropdown-basic.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbdDropdownBasic } from './dropdown-basic';
@NgModule({
imports: [BrowserModule, NgbModule],
declarations: [NgbdDropdownBasic],
exports: [NgbdDropdownBasic],
bootstrap: [NgbdDropdownBasic]
})
export class NgbdDropdownBasicModule {}
# dropdown-basic.ts
import {Component} from '@angular/core';
@Component({
selector: 'ngbd-dropdown-basic',
templateUrl: './dropdown-basic.html'
})
export class NgbdDropdownBasic {
public outputFormats = ["pdf", "png32", "png8", "jpg", "gif", "eps", "svg"];
}
# dropdown-basic.html
<div ngbDropdown >
<button id="dropdownBasic1" ngbDropdownToggle>
Toggle dropdown
</button>
<div ngbDropdownMenu aria-labelledby="polylineStyleDropdown">
<button
ngbDropdownItem
*ngFor="let format of outputFormats"
>
{{format}}
</button>
</div>
</div>
If it's not working for you with this exact setup, then this error may be a red herring and you could have your hands full with isolating exactly what's causing it to break. We don't have enough insight into your surrounding code to really diagnose this. Hopefully you spot something that's obvious and different from this example.
CodePudding user response:
The issue was not related to the code that was in the question. I made a mistake in assigning enum to a property called printModes
then I used that property in another ngFor in the template.
Error:
enum PrintModes {
CurrentView = 'Current View',
AdjustableBox = 'Adjustable Box',
DrawnBoundary = 'Drawn Boundary'
}
Then inside the component:
public printModes = PrintModes
In the template:
<div ngbDropdown >
<button ngbDropdownToggle>
{{printMode}}
</button>
<div ngbDropdownMenu aria-labelledby="polylineStyleDropdown">
<button *ngFor="let area of printModes"
(click)="onPrintAreaChanged(area)">{{area}}
</button>
</div>
</div>
The error in the forked stackblitz is correct and relevant to the mistake but in my app, it does not show the original error. Somehow, the original error made typescript misbehave.
Stackblitz error:
Error in src/app/dropdown-basic.html (7:54)
Type 'typeof PrintModes' is not assignable to type 'NgIterable<any>'.
Type 'typeof PrintModes' is not assignable to type 'Iterable<any>'.
To fix the issue, inside the component I just need to change
public printModes = PrintModes;
To
public printModes = Object.values(PrintModes);