繁体   English   中英

Angular 5 HTTP 响应未定义

[英]Angular 5 HTTP response undefined

我正在使用 angular 和 nodejs 以及 express 进行一个小型的全栈项目。 我有一个问题,我在 dataservice 中的方法之一没有返回数据并且已经调试它,它指出返回值是未定义的。

//客户端

俱乐部.ts

export interface Clubs {
  id?: number;
  club_name: string;
  specific_category_id?: number;
  club_category_id?: number;
  county_id?: number;
}

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { NavbarComponent } from './components/navbar/navbar.component';
import { HomeComponent } from './components/home/home.component';
import { ClubsComponent } from './components/clubs/clubs.component';
import { SearchByCountiesComponent } from './components/search-by-counties/search-by-counties.component';
import { SearchByClubsComponent } from './components/search-by-clubs/search-by-clubs.component';
import { SearchSportsComponent } from './components/search-sports/search-sports.component';
import { SearchClubsComponent } from './components/search-clubs/search-clubs.component';    

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'club-category/search', component: SearchByClubsComponent },
  { path: 'club-category/search/:county_id', component: SearchByClubsComponent },
  { path: 'counties/search', component: SearchByCountiesComponent },
  { path: ':slug/search', component: SearchSportsComponent },
  { path: ':slug/search/:countyID', component: SearchSportsComponent },
  { path: 'clubs/search', component: SearchClubsComponent },
  { path: 'club/:id', component: ClubsComponent }
]

@NgModule({
  exports: [RouterModule],
  imports: [
    RouterModule.forRoot(routes)
  ],
  declarations: []
})
export class AppRoutingModule { }

search-club-component.ts

import { Component, OnInit } from '@angular/core';
import { Clubs } from '../../models/clubs';
import { DataService } from '../../services/data.service';

@Component({
  selector: 'app-search-clubs',
  templateUrl: './search-clubs.component.html',
  styleUrls: ['./search-clubs.component.scss']
})
export class SearchClubsComponent implements OnInit {
  //Declare Properties
  clubs: Clubs[];

    constructor(
      private dataService: DataService
    ) { }

  ngOnInit() {
    //Get all Clubs
    this.dataService.getClubs().subscribe(clubs => {
      console.log('Response has been received ');
      this.clubs = clubs;            
    });
  }

}

数据服务.ts

import { Injectable } from "@angular/core";    
import { Observable } from "rxjs/Observable";    
import { ClubType } from "../models/clubtype";
import { County } from "../models/county";
import { SportCategory } from "../models/SportCategory";
import { Clubs } from "../models/Clubs";    
import { HttpClientModule, HttpClient } from "@angular/common/http";

@Injectable()
export class DataService {
  //Declare properties
  localHost = "http://localhost:3000";

  constructor(private httpClient: HttpClient) {}

  //Get ClubTypes
  getClubTypes(): Observable<ClubType[]> {
    return this.httpClient.get<ClubType[]>(
      this.localHost + "/club-category/search"
    );
  }

  //Get ClubTypes
  getClubTypesByCounty(countyID): Observable<ClubType[]> {
    return this.httpClient.get<ClubType[]>(
      this.localHost + '/club-category/search/'+ countyID
    );
  }

  //Get Counties
  getCounties(): Observable<County[]> {
    return this.httpClient.get<County[]>(this.localHost + "/counties/search");
  }

  //Get Counties
  getSportCategory(slug): Observable<SportCategory[]> {
    return this.httpClient.get<SportCategory[]>(
      this.localHost + '/'+ slug +'/search'
    );
  }

  //Get Specific Category By County
  getSportCategoryByCounty(slug, countyID): Observable<SportCategory[]> {
    return this.httpClient.get<SportCategory[]>(
      this.localHost + '/'+ slug +'/search/' + countyID
    );
  }

  //Get Clubs
  getClubs(): Observable<Clubs[]> {        
    return this.httpClient.get<Clubs[]>(this.localHost + "/clubs/search"); 
  }
}

//服务端

应用程序.js

const express = require("express");
const path = require('path');
const mysql = require('mysql');
const connectionPool = require('./config/database');

//Create Connection
const db = mysql.createConnection({
  host:'localhost',
  user: 'someUser',
  password: '******',
  database: 'dataBaseName'
});

db.connect((err) =>{
  if(err){
    console.log(err);
    throw err;
  }
  console.log('MySQL connected...');
});

const app = express();

//JSON Prettify
app.set('json spaces', 40);

// Add headers
app.use(function (req, res, next) {

  // Website you wish to allow to connect
  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');

  // Request methods you wish to allow
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

  // Request headers you wish to allow
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

  // Set to true if you need the website to include cookies in the requests sent
  // to the API (e.g. in case you use sessions)
  res.setHeader('Access-Control-Allow-Credentials', true);

  // Pass to next layer of middleware
  next();
});  

//Set Routes
const clubcategories = require('./routes/club-categories');
const counties = require('./routes/counties');
const sportcategories = require('./routes/sport-categories');
const clubs = require('./routes/clubs');


//Use Routes
app.use('/club-category', clubcategories);
app.use('/counties', counties);
app.use('/sport', sportcategories);
app.use('/clubs', clubs);


//Set port
const port = process.env.PORT || 3000;

//Set up server
app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

俱乐部.js

const express = require("express");
const router = express.Router();
const connectionPool = require('../config/database');

//Get clubs
router.get("/search", (req, res) => {
  //Get connection from connection pool
  connectionPool.getConnection((err, dbConnection) =>{
    if(err){
      console.log(err);
    } else{
      let sql = 'Select * FROM clubs';

      let query = dbConnection.query(sql, (err, clubs)=> {
        if(err) console.log(err);
        console.log(clubs);
        //res.status(200).send(clubs);
        res.json(clubs);
      });

      //release connection back to pool
      dbConnection.release();
    }
  });
});

module.exports = router;

在服务器端接收请求并执行代码。 我看到在发送响应之前记录在服务器端控制台上的俱乐部对象数组。 但是,在客户端响应未定义(如我调试时所见)永远不会输出我在客户端登录的“已收到响应”行。

我对服务器的其他四个调用也遵循了相同的方法,并且没有出现任何问题。 在这种情况下,我看不出我哪里出错了。 你能帮忙找出问题吗?

更新服务方法如下

//Get Clubs
    getClubs(): Observable<Clubs[]> {
       return this.httpClient.get<Clubs[]>(this.localHost + "/clubs/search").map(response => response.json());    
    }

在您的服务端 clubs.js 中,您缺少 res.json(clu​​bs) 之前的返回 这就是为什么它不返回任何值。

编辑:或者更好地使用新的 res.status(200).send(clubs) 代替。

我发现了这个问题。 它与 Http 响应无关。 我检查了 Chrome 中的网络,看到浏览器收到了响应。 我使用了 Augury 扩展(对于 Angular)并看到路由器实际上路由回 SearchSportsComponent 而不是 SearchClubsComponent。

我按照下面概述的顺序重新排序并解决了问题。 我需要进一步了解路由以了解为什么会这样。 希望这将是其他人的未来。

代码更改如下所示:

app-routing.module.ts

    const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'club-category/search', component: SearchByClubsComponent },
  { path: 'club-category/search/:county_id', component: SearchByClubsComponent },
  { path: 'counties/search', component: SearchByCountiesComponent },
  { path: 'clubs/search', component: SearchClubsComponent },
  { path: ':slug/search', component: SearchSportsComponent },
  { path: ':slug/search/:countyID', component: SearchSportsComponent },  
  { path: 'club/:id', component: ClubsComponent }
]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM