Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
150
How to populate a grid from WebAPI
posted

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);