I am trying to populate a grid from a WebAPI call and i'm getting the following error in Chrome. I have broken the call to the webapi into a service component. What am I doing wrong?
IgxGridComponent.html:1 ERROR Error: Cannot find a differ supporting object "[object Object]" of type "object". NgFor only supports binding to Iterables such as Arrays.
Here is my code. It is a VS2017 solution with the WEBAPI written in DotNet Core 2.0.
//FuelTankController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Fuel.PosModel; using Fuel.PosModel.Views; namespace Fuel.Controllers { [Route("api/[controller]")] public class FuelTankController : Controller { private readonly CustomerMajorOilPosDataContext _context; public FuelTankController(CustomerMajorOilPosDataContext context) { _context = context; } [HttpGet("[action]")] public IEnumerable<FuelTankReadingView> GetTankReadings() { return LoadTankReadings(); } private IQueryable<FuelTankReadingView> LoadTankReadings() { var reading = from r in _context.TankRequest join d in _context.TankDetail on r.TankRequestId equals d.TankRequestId group new { r, d } by new { d.Tank, d.ProductCode } into g select g.OrderByDescending(t => t.r.RequestDateTime).FirstOrDefault() into h select new PosModel.Views.FuelTankReadingView() { RequestDateTime = h.r.RequestDateTime, Tank = h.d.Tank, Name = string.Format("Tank {0}", h.d.Tank), LocalName = string.Format("Tank {0}", h.d.Tank), ProductCode = h.d.ProductCode, Volume = h.d.Volume, TCVolumne = h.d.Tcvolume, Ullage = h.d.Ullage }; return reading; } } } //FuelTankReadingView.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Fuel.PosModel.Views { public class FuelTankReadingView { public string LocalName { get; set; } public string Name { get; set; } public DateTime? RequestDateTime { get; set; } public int? Tank { get; set; } public int? ProductCode { get; set; } public double? Volume { get; set; } public double? TCVolumne { get; set; } public double? Ullage { get; set; } } } //Package.json { "name": "Fuel", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "postinstall": "webpack --config webpack.config.vendor.js --display-error-details" }, "private": true, "dependencies": { "@angular/animations": "^5.0.0", "@angular/common": "^5.0.0", "@angular/compiler": "^5.0.0", "@angular/core": "^5.0.0", "@angular/forms": "^5.0.0", "@angular/http": "^5.0.0", "@angular/platform-browser": "^5.0.0", "@angular/platform-browser-dynamic": "^5.0.0", "@angular/platform-server": "^5.0.0", "@angular/router": "^5.0.0", "@ngtools/webpack": "1.8.0", "@types/webpack-env": "1.13.0", "angular2-template-loader": "0.6.2", "aspnet-prerendering": "^3.0.1", "aspnet-webpack": "^2.0.3", "awesome-typescript-loader": "3.2.1", "bootstrap": "3.3.7", "css": "2.2.1", "css-loader": "0.28.4", "es6-shim": "0.35.3", "event-source-polyfill": "0.0.9", "expose-loader": "0.7.3", "extract-text-webpack-plugin": "3.0.2", "file-loader": "0.11.2", "html-loader": "0.4.5", "igniteui-angular": "^5.3.0", "isomorphic-fetch": "2.2.1", "jquery": "3.2.1", "json-loader": "0.5.4", "jszip": "^3.1.5", "loader-utils": "^1.1.0", "node-sass": "^4.8.3", "preboot": "4.5.2", "raw-loader": "0.5.1", "reflect-metadata": "0.1.10", "rxjs": "5.5.6", "style-loader": "0.18.2", "to-string-loader": "1.1.5", "url-loader": "0.5.9", "web-animations-js": "^2.3.1", "webpack": "^3.1.0", "webpack-hot-middleware": "2.18.2", "webpack-merge": "4.1.0", "zone.js": "0.8.12" }, "devDependencies": { "@angular/cli": "1.5.0", "@angular/compiler-cli": "^5.0.0", "@angular-devkit/core": "0.0.29", "@angular/language-service": "^5.0.0", "@types/chai": "4.0.1", "@types/jasmine": "~2.5.53", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "chai": "4.0.2", "codelyzer": "^4.3.0", "jasmine-core": "~2.6.2", "jasmine-spec-reporter": "~4.1.0", "karma": "~1.7.0", "karma-chai": "0.1.0", "karma-chrome-launcher": "~2.1.1", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "karma-webpack": "^3.0.0", "protractor": "~5.1.2", "popper.js": "1.14.3", "sass-loader": "6.0.6", "tslint": "~5.7.0", "ts-node": "~3.2.0", "typescript": "~2.4.2" } } //app.module.shared.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { RouterModule } from '@angular/router'; import { IgxGridModule, IgxIconModule, IgxSwitchModule } from 'igniteui-angular/main'; import { AppComponent } from './components/app/app.component'; import { NavMenuComponent } from './components/navmenu/navmenu.component'; import { HomeComponent } from './components/home/home.component'; import { FetchDataComponent } from './components/fetchdata/fetchdata.component'; import { CounterComponent } from './components/counter/counter.component'; import { IgxGridSampleComponent } from './components/igxGridSample/igxGridSample.component'; import { FuelTankComponent } from './components/fueltank/fueltank.component'; import { BrowserModule } from '@angular/platform-browser'; @NgModule({ declarations: [ AppComponent, NavMenuComponent, CounterComponent, FetchDataComponent, HomeComponent, IgxGridSampleComponent, FuelTankComponent ], imports: [ CommonModule, HttpModule, HttpClientModule, BrowserModule, FormsModule, IgxGridModule.forRoot(), IgxSwitchModule, RouterModule.forRoot([ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'counter', component: CounterComponent }, { path: 'fetch-data', component: FetchDataComponent }, { path: 'grid-sample', component: IgxGridSampleComponent }, {path: 'fuel-tank', component: FuelTankComponent }, { path: '**', redirectTo: 'home' } ]) ] }) export class AppModuleShared { } //fueltank.component.html <igx-grid #grid1 id="grid1" [data]="fuelTanks" height="505" autoGenerateCollumn="false"> <!--<igx-column field="Store" header="Store" sortable="true" width="250"></igx-column>--> <igx-column field="Name" header="Tank" sortable="true" width="250"></igx-column> <igx-column field="ProductCode" header="Product" sortable="true" width="250"></igx-column> </igx-grid> //fueltank.component.ts import { Component, OnInit, Injectable, ViewEncapsulation, ViewChild, NgModule, Inject } from '@angular/core'; import { IgxGridComponent } from 'igniteui-angular/grid/grid.component'; import { IgxGridCellComponent } from 'igniteui-angular/grid/cell.component'; //import { athletesData } from './services/data'; import { IgxGridModule } from 'igniteui-angular/main'; //import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Rx'; import { FuelTankService, FuelTankRecord } from './fueltank.service'; import { Http, HttpModule } from '@angular/http'; @Component({ selector: 'fueltank', templateUrl: "./fueltank.component.html", styleUrls: ['./fueltank.component.scss'], providers: [FuelTankService], encapsulation: ViewEncapsulation.None }) export class FuelTankComponent implements OnInit { @ViewChild('grid1', { read: IgxGridComponent }) public grid1: IgxGridComponent; private fuelTanks: Observable<FuelTankRecord[]>; errorMessage: string; private windowWidth: any; constructor(private fuelTankService: FuelTankService, @Inject('BASE_URL') baseUrl: string) { } ngOnInit(): void { this.fuelTanks = this.fuelTankService.fetchData(); this.errorMessage = 'test'; } } //fueltank.service.ts import { Injectable, Inject } from '@angular/core'; import { HttpClient, HttpResponse, HttpRequest, HttpEventType } from '@angular/common/http'; //import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Rx'; import { of } from 'rxjs/observable/of'; import { catchError, map } from 'rxjs/operators'; //import { Http, HttpModule, Response } from '@angular/http'; import { ErrorHandler } from '@angular/core/src/error_handler'; import 'rxjs/add/operator/map'; //import { Response } from '@angular/http/src/static_response'; export interface FuelTankRecord { LocalName: string; Name: string; RequestDateTime: Date; Tank: number ProductCode: number; Volume: number; TCVolumne: number; Ullage: number; } @Injectable() export class FuelTankService { private url = 'http://localhost:62001/api/FuelTank'; constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) { } fetchData(): Observable<FuelTankRecord[]> { var api = this.baseUrl + 'api/FuelTank/GetTankReadings'; return this.http.get(api).map(response => response as FuelTankRecord[] || []); } private errorHandler<T>(message: string, result: T) { return (error: any): Observable<any> => { console.error('${message}:${error.message}'); return of(result as T); }; } } //fueltank.component.scss @import '../../../../node_modules/igniteui-angular/core/styles/themes/index.scss'; @include igx-core(); @include igx-theme($default-palette);