1

I'm new to angular and mongodb. I'm trying to pull data from MongoDB and display it in an Angular Material Table. But i got a error

"ERROR TypeError: Cannot read property 'data' of undefined"

when i tried to open the app and the data from MongoDB won't load. I manage to narrow down the problem that is something to do with this line.

return this.myservice.GetList().subscribe(res => this.dataSource.data = res["0"]["data"]);
                                                                                ^^^^^^^^

Thanks in advance!

tabledata.component.ts

import {BackendService} from './../backend.service';
import {Component, OnInit, ViewChild} from '@angular/core';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';


@Component({
  selector: 'tabledata',
  templateUrl: './tabledata.component.html',
  styleUrls: ['./tabledata.component.css']
})

export class TabledataComponent implements OnInit {
  displayedColumns = ['S_NAME', 'S_ADD', 'S_STATUS'];
  dataSource = new MatTableDataSource();

  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
  @ViewChild(MatSort, {static: true}) sort: MatSort;

  constructor(private myservice: BackendService) {
  }



  ngOnInit() {

    return this.myservice.GetList().subscribe(res => this.dataSource.data = res["0"]["data"]);

  }

  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }
}

MongoDB Data in sitelist Collection

{
    "_id" : ObjectId("5ec4672e44f01dcae82c3dde"),
    "error" : "0",
    "num_rows" : 3,
    "data" : [ 
        {
            "S_NAME" : "SBOBETH",
            "S_ADD" : "sbobeth.com",
            "S_STATUS" : "UP"
        }, 
        {
            "S_NAME" : "GTRCASINO",
            "S_ADD" : "gtrcasino.com",
            "S_STATUS" : "DOWN"
        }, 
        {
            "S_NAME" : "SBOBETH",
            "S_ADD" : "sbobeth.com",
            "S_STATUS" : "DOWN"
        }, 
        {
            "S_NAME" : "GTRBETCLUB",
            "S_ADD" : "gtrbetclub.com",
            "S_STATUS" : "UP"
        }, 
        {
            "S_NAME" : "77UP",
            "S_ADD" : "77up.bet.com",
            "S_STATUS" : "UP"
        }, 
        {
            "S_NAME" : "DATABET88",
            "S_ADD" : "databet88.net",
            "S_STATUS" : "DOWN"
        }, 
        {
            "S_NAME" : "FAFA855",
            "S_ADD" : "fafa855.com",
            "S_STATUS" : "UP"
        }
    ]
}

backend.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders, HttpRequest  } from "@angular/common/http";
import { catchError, map, tap,  } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class BackendService {

  constructor(private _http: HttpClient) { }

  GetList() 
  {

    return this._http.get('http://localhost:3000/api/getList')

  }

  private handleError<T>(operation = 'operation', result?: T)
  {
    console.log("error");
    return null;
  }

  private log(message: string)
  {
    console.log("log");
  }

}

server.js

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
var mongoose = require('mongoose');
require('./db')                                                                         
const SLDBModel = require('./sldbreply_schema');                                        

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.urlencoded({ extended: true }))

app.use(function (req, res, next)
{
    res.setHeader('Access-Control-Allow-Origin','*');
    res.setHeader('Access-Control-Allow-Methods','GET, POST, PUT, DELETE');
    res.setHeader('Access-Control-Allow-Headers','content-type, x-access-token');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});

app.get('/api/getList', function(req, res){
    SLDBModel.find({},function(err,data){
        if(err)
        {
            res.send(err);
        }
        else
        {
            res.send(data);
        }
    });
})

app.listen(3000, ()=>
{
    console.log("SERVER IS ONLINE!");
})

After i tried console.log(res); from suggestion in the comment to check my 'res' data first.

enter image description here

and from server.js i tried console.log(data);

enter image description here

Both of them return [] not sure what this mean Any suggestion on how to fix?

3
  • 2
    Whats the response data? If it as described in "MongoDB Data in sitelist Collection", then this object is not a list. res[0] you want res["data"][0] to get the first result Commented May 20, 2020 at 17:03
  • Check if your res["0"] contains a key name ddata, probably the response data has issue. Check the GetList service for the data it is returning. Commented May 20, 2020 at 17:09
  • I think you're right that my mongo collection is the problem. i tried console.log(res); but it don't reply me anything Commented May 20, 2020 at 18:02

3 Answers 3

1

Inside ngOnInit() replace

return this.myservice.GetList().subscribe(res => this.dataSource.data = res["0"]["data"]);

with

this.myservice.GetList().subscribe(res => {
        console.log(res); // Check your 'res' data first
        dataSource.data = res["0"]["data"];
    });

Note: console your res to know how is your response data.

Sign up to request clarification or add additional context in comments.

5 Comments

console.log(res); return [] please look at my new screenshot
In your service replace "return this._http.get('localhost:3000/api/getList')" with "return this._http.get('localhost:3000/api/getList').map(res => res.json());" and console again. Please share the result in text instead of sharing screenshots.
Oh sorry it my first time asking here. the error would occur at .map Property 'map' does not exist on type 'Observable<Object>'.
import 'rxjs/Rx'; in service
import { Observable } from 'rxjs'; the same error would still occur
0

It appears the data property is the parent level of the object. Try the following in the ngOnInit()

ngOnInit() {
  this.myservice.GetList().subscribe(
    res => { 
      this.dataSource.data = res['data'];
    },
    error => { 
      // always good practice to handle error in HTTP observables
    }
  );
}

5 Comments

It reply "ERROR TypeError: Cannot read property 'length' of undefined"
Could you please post the code where the length property is accessed?
Please check the code again. The error message is Cannot read property 'length'.
The length property is from Standard built-in objects of Array. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
It is used to access the length of an array in user applications. And from the screenshot it appears the array is empty. You need to verify how the data is accessed from the backend and if the backend sends the correct data. And go through Angular Tour of Heroes tutorial. It introduces some basics of Angular.
0

Try converting data to Json on your server side as well

app.get('/api/getList', function(req, res){
SLDBModel.find({},function(err,data){
    if(err)
    {
        res.send(err);
    }
    else
    {
        res.send(data.toJSON());
    }
   });
})

Try console.log(data) as well.If it is an array please replace res.send(data) by res.send(data.map(v => v.toJSON())

1 Comment

console.log(data) return [] see my new screenshot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.