MEAN-Stack - не удается прочитать вторую таблицу SQL с сервера - PullRequest
0 голосов
/ 04 декабря 2018

Я разрабатываю WebApp с MEANStack, используя Sequelize для доступа к базам данных SQL.Мне удалось прочитать, с кодом ниже, таблицу SQL.К сожалению, я получаю следующую ошибку на стороне клиента при попытке прочитать второй SQL (Изменить после первого ответа)

Table: core.js:1673 ERROR TypeError: tableData.processTables.map is not a function at MapSubscriber.project (tables.service.ts:32)

tables.service.ts: 32 ошибка:

        processTables: tableData.processTables.map(table => {

А вот как выглядит ошибка на стороне клиента: Таблица: core.js: 1673 ОШИБКА TypeError: tableData.processTables.map не является функцией в MapSubscriber.project

Вот мой код (изменить)

tables-list.component.html

<mat-spinner *ngIf="isLoading"></mat-spinner>
  <h1 class="mat-body-2">Process List &nbsp; </h1>

  <mat-accordion multi="true" *ngIf="userIsAuthenticated && !isLoading">
    <mat-expansion-panel>
      <mat-expansion-panel-header>
        Process List
      </mat-expansion-panel-header>
  <table mat-table [dataSource]="processTables" matSort class="mat-elevation-z8" *ngIf="userIsAuthenticated">

      <!-- ProcessName Column -->
      <ng-container matColumnDef="ProcessName">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> ProcessName </th>
        <td mat-cell *matCellDef="let element"> {{element.ProcessName}} </td>
      </ng-container>

      <!-- PackageVersion Column -->
      <ng-container matColumnDef="PackageVersion">
          <th mat-header-cell *matHeaderCellDef mat-sort-header> PackageVersion </th>
          <td mat-cell *matCellDef="let element"> {{element.PackageVersion}} </td>
        </ng-container>

      <!-- RobotType Column -->
      <ng-container matColumnDef="RobotType">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> RobotType </th>
        <td mat-cell *matCellDef="let element"> {{element.RobotType}} </td>
      </ng-container>

      <!-- PackagePath Column -->
      <ng-container matColumnDef="PackagePath">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> PackagePath </th>
        <td mat-cell *matCellDef="let element"> {{element.PackagePath}} </td>
      </ng-container>

      <!-- CreationTime Column -->
      <ng-container matColumnDef="CreationTime">
          <th mat-header-cell *matHeaderCellDef mat-sort-header> CreationTime </th>
          <td mat-cell *matCellDef="let element"> {{element.CreationTime}} </td>
        </ng-container>

      <!-- Status Column -->
      <ng-container matColumnDef="Status">
          <th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th>
          <td mat-cell *matCellDef="let element"> {{element.Status}} </td>
        </ng-container>

      <tr mat-header-row *matHeaderRowDef="displayedprocessTablesColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedprocessTablesColumns;"></tr>
    </table>
  </mat-expansion-panel>
</mat-accordion>

    <br> <h1 class="mat-body-2">Applications List &nbsp; </h1>

tables-list.component.ts:

import { Component, OnInit, OnDestroy } from "@angular/core";
import { ProcessTable, ApplicationsTable } from "./tables.model";
import { PageEvent } from "@angular/material";

import { Subscription } from "rxjs";
import { TablesService } from "./tables.service";
import { AuthService } from "../auth/auth.service";

@Component({
  // We load the component via routing and therefore we do not need a selector
  selector: "app-tables",
  templateUrl: "./tables-list.component.html",
  styleUrls: ["./tables-list.component.css"]
}) // Turn class into component by adding @Component Decorator

export class TableListComponent implements OnInit, OnDestroy {
  processTables: ProcessTable[] = [];
  applicationsTables: ApplicationsTable[] = [];
  isLoading = false;
  totalTables = 0;
  tablesPerPage = 5;
  currentPage = 1;
  pageSizeOptions = [1, 2, 5, 10];
  displayedprocessTablesColumns: string[] = ["ProcessName", "PackageVersion", "RobotType", "PackagePath", "CreationTime", "Status" ];
  displayedApplicationsTablesColumns: string[] = ["ProcessName", "PackageVersion" ];
  userIsAuthenticated = false;
  userId: string;
  isAdmin: boolean;

  private tablesSub: Subscription;
  private authStatusSub: Subscription;

  constructor(
    public tablesService: TablesService,
    private authService: AuthService
  ) {}

  ngOnInit() {
    this.isLoading = true;
    this.tablesService.getProcessTables(this.tablesPerPage, this.currentPage);
    this.userId = this.authService.getUserId();
    this.tablesSub = this.tablesService
      .getTableUpdateListener()
      .subscribe((tableData: { processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; tableCount: number }) => {
        this.isLoading = false;
        this.totalTables = tableData.tableCount;
        this.processTables = tableData.processTables;
        this.applicationsTables = tableData.applicationsTables;
      });
    this.userIsAuthenticated = this.authService.getIsAuth();
    // console.log("Is authenticated: " + this.userIsAuthenticated);
    this.authStatusSub = this.authService
      .getAuthStatusListener()
      .subscribe(isAuthenticated => {
        this.userIsAuthenticated = isAuthenticated;
      });
  }

  onLogout() {
    this.authService.logout();
  }

  ngOnDestroy() {
    this.tablesSub.unsubscribe();
    this.authStatusSub.unsubscribe();
  }
}

Tables.service.ts:

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Subject } from "rxjs";
import { map } from "rxjs/operators";
import { Router } from "@angular/router";

import { environment } from "../../environments/environment";
import { ProcessTable, ApplicationsTable } from "./tables.model";

const BACKEND_URL = environment.apiUrl + "/tables/";

@Injectable({ providedIn: "root" })
export class TablesService {
  private processTables: ProcessTable[] = [];
  private applicationsTables: ApplicationsTable[] = [];
  private tablesUpdated = new Subject<{ processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; tableCount: number }>();

  constructor(private http: HttpClient, private router: Router) {}

  getProcessTables(tablesPerPage: number, currentPage: number) {
    const queryParams = `?pagesize=${tablesPerPage}&page=${currentPage}`;
    this.http
      .get<{ processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; maxTables: number }>(
        BACKEND_URL + queryParams
      )
      .pipe(
        map((tableData: { processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; maxTables: number }) => {
          console.log(tableData);
          console.log(tableData.processTables);
          console.log(tableData.applicationsTables);
          return {
            processTables: tableData.processTables.map(table => {
              return {
                ProcessName: table.ProcessName,
                PackageVersion: table.PackageVersion,
                RobotType: table.RobotType,
                PackagePath: table.PackagePath,
                CreationTime: table.CreationTime,
                Status: table.Status
              };
            }),
             applicationsTables: tableData.applicationsTables.map(table => {
              return {
                ProcessName: table.ProcessName,
                PackageVersion: table.PackageVersion,
                WorkflowsBelongingToProcess: table.WorkflowsBelongingToProcess,
                ApplicationsBelongingToWorkflow: table.ApplicationsBelongingToWorkflow
              };
            }),
            maxTables: tableData.maxTables
          };
        })
      )
      .subscribe(transformedTablesData => {
        this.processTables = transformedTablesData.processTables;
        this.tablesUpdated.next({
          processTables: [...this.processTables],
          applicationsTables: [...this.applicationsTables],
          tableCount: transformedTablesData.maxTables
        });
      });
  }

  getTableUpdateListener() {
    return this.tablesUpdated.asObservable();
  }
}

Таблицы \ model.ts:

export interface Table {
  ProcessName: string;
  PackageVersion: string;
  RobotType: string;
  PackagePath: string;
  CreationTime: string;
  Status: string;
}

export interface ApplicationsTable {
  ProcessName: string;
  PackageVersion: string;
  WorkflowsBelongingToProcess: string;
  ApplicationsBelongingToWorkflow: string;
}

Backend \ controllers \ tables.js:

const sequelize = require("../sequelize");

const getProcessTables = (req, res) => {
  return sequelize
    .query("SELECT * FROM dbo.Process", { type: sequelize.QueryTypes.SELECT })
    .then(fetchedtables => {
      return {
        message: "Process table fetched from the server",
        processTables: fetchedtables,
        maxProcessTables: fetchedtables.length
      };
    });
};

const getApplicationsTables = (req, res) => {
  return sequelize
    .query("SELECT * FROM dbo.Applications", {
      type: sequelize.QueryTypes.SELECT
    })
    .then(fetchedtables => {
      return {
        message: "Applications Table fetched from the server",
        applicationsTables: fetchedtables,
        maxApplicationsTables: fetchedtables.length
      };
    });
};

exports.getAllTables = (req, res) => {
  return Promise.all([
    getApplicationsTables(req, res),
    getProcessTables(req, res)
  ]).then(tables => {
    res.status(200).json({
      applicationsTables: tables[0],
      processTables: tables[1]
    });
  });
};

Backend \ rout \ tables.js:

const express = require("express");

const TableController = require("../controllers/tables")

const router = express.Router({ mergeParams: true });

router.get("", TableController.getAllTables);

module.exports = router;

Как это исправить?Большое спасибо Дженнаро

1 Ответ

0 голосов
/ 04 декабря 2018

Я вижу две ошибки.

  • Вы запрашиваете маршрут /tables/, но не определяете маршрут.
  • Вы создали два обработчика запросов и использовали один и тот же маршрут.Что делает, так это запрос идет в первый блок app.get.Не второй.

Итак, сначала вам нужно объединить getProcessTable и getApplicationTable в одну консолидированную функцию.

const sequelize = require("../sequelize");

const getProcessTables = (req, res) => {
  return sequelize.query("SELECT * FROM dbo.Process", { type: sequelize.QueryTypes.SELECT})
  .then(fetchedtables => {
    return {
      message: "Process table fetched from the server",
      processTables: fetchedtables,
      maxProcessTables: fetchedtables.length
    };
  });
};

const getApplicationsTables = (req, res) => {
  return sequelize.query("SELECT * FROM dbo.Applications", { type: sequelize.QueryTypes.SELECT})
  .then(fetchedtables => {
    return {
      message: "Applications Table fetched from the server",
      applicationsTables: fetchedtables,
      maxApplicationsTables: fetchedtables.length
    };
  });
};

exports.getAllTables = (req, res) =>{
    return Promise.all([getApplicationsTables(req,res), getProcessTables(req,res)])
    .then(tables =>{
        res.status(200).json({
            applicationsTables: tables[0],
            processTables: tables[1]
          });
    })
}

, а затем, возможно, направить ее в таблицы

router.get("/tables/", TableController.getAllTables);

Теперь вам нужно изменить строку map.

processTables: tableData.processTables.map будет,

processTables: tableData.processTables.processTables.map(table => {
...