sql - MEAN-Stack - 无法从服务器读取第二个 SQL 表

标签 sql node.js angular sequelize.js mean-stack

我正在使用 MEANStack 开发 WebApp,使用 Sequelize 访问 SQL 数据库。我设法用下面的代码阅读了一个 SQL 表。不幸的是,当我尝试读取第二个 SQL 时,客户端出现以下错误(第一个答案后编辑)

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

table.service.ts:32 的错误是:
        processTables: tableData.processTables.map(table => {

这是客户端错误的样子:
Table: core.js:1673 ERROR TypeError: tableData.processTables.map is not a function at MapSubscriber.project

这是我的代码(编辑)

表-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>

表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();
  }
}

表.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;
}

后端\ Controller \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]
    });
  });
};

后端\路由\tables.js:
const express = require("express");

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

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

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

module.exports = router;

我该如何解决?
非常感谢
真纳罗

最佳答案

我可以看到两个错误。

  • 您正在查询 /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 => {
    

    关于sql - MEAN-Stack - 无法从服务器读取第二个 SQL 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53620918/

    相关文章:

    php - SQL试图根据年龄列中的年龄组创建排名列

    javascript - Controller 文件中的 JavaScript 日志中的语法错误

    angular - 如何使用复选框在 ng2-smart-table 组件中选择多行?

    javascript - 迭代对象数组以创建后列表

    javascript - 如何使用discord.js获取特定成员(member)用户名

    json - 如何在 Angular 中连接两个对象?

    SQL删除表中的重复项

    mysql - 如果使用 SQL 某些表中存在行,则更新表行

    mysql - 我无法使用选择查询插入列

    javascript - Selenium Webdriver (node.js) 截屏并保存测试结果