使用要表达的对象数组进行 Angular Post 调用不起作用,甚至无法相互交谈

问题描述 投票:0回答:1

我正在处理一个特定的 Post 调用,该调用传递一个数组,该数组不想与我创建的用于进行 MySQL 查询的 Express Node.js 服务器通信。这是启动整个事情的方法代码:

    questionsSubmit(){
    console.log('Questions Submited')
    // Initialize an array to store the answers
    const answers: {participantId: number, optionId: number, scorePoints: number}[] = [];
    
    // Iterate over the form controls
    Object.keys(this.questionsForm.controls).forEach(key => {
      const control = this.questionsForm.controls[key]
      
      // Check if the control is a FormGroup and contains 'value' property
      if (control instanceof FormControl && control.value) {

        const participantId = this.participantId
        const [optionId, scorePoints] = control.value.split('-').map(Number)
        
        // Create an Answer object and push it to the answers array
        answers.push({
          participantId,
          optionId,
          scorePoints
        })
      }
    })
    if(!this.participantId){
      this.showAlert = true
      this.step = 0
      console.log('Please complete and submit the Participant\'s profile before submitting to the Needs questionnaire' )
      return
    }
    if(this.questionsForm.valid){
      
      this.masterService.saveAnswers(answers)
    }
    // console.log(answers);
  }

此 Component.ts 代码可以很好地收集所有必要的 FormControl 并组装对象数组。我已经验证了数百万次,这始终是 console.log 的结果 然后它调用 Service.ts 方法将数组发布到服务器。方法如下:

saveAnswers(answers: {participantId: number, optionId: number, scorePoints: number}[]){

 return this.http.post<{participantId: number, optionId: number, scorePoints: number}[]>(`http://localhost:3000/hello`, answers, this.httpOptions)
 .pipe(catchError(this.errorHandlerService.handleError<any>("post")));
 
}   

但这就是所有通信都消失的地方。浏览器控制台中没有错误,后端终端中也没有错误。我在每个地方都放了一百万个console.logs,但什么也没有,Nada!疯狂的是我有 GET、PUT、DELETE 和其他 POST,而且它们都工作正常。服务器 POST 到数据库也工作得很好。我使用 Postman 推送相同的数据并且有效。

我的服务器由6个文件组成(用于启动服务器的中间件的Index.js,1个路由文件,用于处理请求和响应的控制器,以及用于查询数据库的模型文件,最后2个仅用于处理与数据库的连接)

索引.js

const express = require('express')
const bodyParser = require('body-parser');
const app = express()
const ports = process.env.PORT || 3000
const participantRoutes = require('./routes/participant-routes')
const questionRoutes = require('./routes/question-routes')
const errorController = require('./controllers/error')

// Middleware to parse JSON bodies
app.use(express.json())
// app.use(bodyParser.json())

app.use((req, res, next) => {
console.log(`Incoming request: ${req.method} ${req.url}`);
next();
});

app.use((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, Authorization')
next()
})

// Routes
app.use('/participants', participantRoutes);

app.use('/hello', questionRoutes);
// http://localhost:3000/questions-options-answers

app.use(errorController.get404)
app.use(errorController.get500)


app.listen(ports, () => console.log(`Hello_Kitty (Server): listening on port ${ports}`))

路由器.js

const express = require('express')
const controller = require('../controllers/controller')
const router = express.Router()

// Question Routes
router.get('/', controller.getAllQuestionsWithOptions);
router.post('/', controller.postAnswersFromOptions);
console.log('Hello From Routes')

module.exports = router

控制器.js

const Question = require('../models/question-model')

exports.getAllQuestionsWithOptions = async (req, res, next) => {
  try {
    const questionsWithOptions = await Question.fetchAllQuestions()
    res.status(200).json(questionsWithOptions)
  } catch (error) {
    console.error('Error fetching questions with options:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

exports.postAnswersFromOptions = async (req, res, next) => {
  try {
    console.log('From postAnswersFromOptions')
    console.log(req.body)
    const postAnswersWithOptions = await Question.postsAnswers(req.body)
    res.status(200).json(postAnswersWithOptions)
  } catch (error) {
    console.error('Error fetching questions with options:', error)
    res.status(500).json({ error: 'Internal server error' })
  }
}

模型.js

const db = require('../util/database')
const Query = require('./query-builder')
const mysql = require('mysql');

module.exports = class Question {
constructor(question, options) {
 this.question = question;
 this.options = options;
}

static async fetchAllQuestions() {
 try {
   // Fetch questions from the database
   const [questions] = await db.execute('SELECT * FROM Questions');

   // Fetch options for each question
   const questionsWithOptions = [];
   for (const question of questions) {
     const [options] = await db.execute('SELECT * FROM Options WHERE questionId = ?', [question.questionId]);
     const formattedOptions = options.map(option => ({ id: option.optionId, option: option.questionOption,
                                                       points: option.points}));
     questionsWithOptions.push({ question: question.question, options: formattedOptions });
   }

   return { questions: questionsWithOptions };
 } catch (error) {
   console.error('Error fetching questions with options:', error);
   throw error
 }
}

static async postsAnswers(answers){
 
 try {
   const columns = Object.keys(answers[0]);

   const values = answers.map(obj => `(${columns.map(col => mysql.escape(obj[col])).join(', ')})`).join(', ');

   const query = `INSERT INTO Answers (${columns.join(', ')}) VALUES ${values}`;

   console.log('Query for post answers')
   console.log(query)
   console.log(values)
   
   return await db.execute(query, [...Object.values(values)])
   
 } catch (error) {
   console.error(error)
   throw error 
 }
 
}

}

如果我将 Postman 与我之前展示的相同数组一起使用,服务器调用工作得很好,数据库也工作得很好,问题是它不想与我的 Angular 应用程序一起工作。除了我提到的那个以外,Express 服务器与其他调用都可以正常工作,最大的问题是我没有从任何地方收到错误。不是来自浏览器控制台,不是来自终端等。请您告诉我我缺少什么或为我指出正确的方向吗?我一直大量使用 ChatGPT,因此我进行了一些广泛的故障排除。我知道问题可能很小,就像经常发生的那样,但我恳求你们提供帮助。

angular express angular-material javascript-objects node.js-connect
1个回答
0
投票

当您调用

saveAnswers
时,它会返回
Observable<...>

Observables 仅在订阅时执行(请参阅 https://angular.io/guide/observables#subscribing)。

当您在第一个代码片段中调用

this.masterService.saveAnswers(answers)
时,它实际上是在调用 saveAnswers 方法,但实际上没有传输任何数据,因为
this.http.post()
在执行任何工作之前正在等待侦听器。

您的前端代码是正确的,不会引发任何错误,因为您可以执行以下操作:

let answersObservable: Observable<any>;
if (this.questionsForm.valid) {
    answersObservable = this.masterService.saveAnswers(answers)
} else {
    answersObservable = this.masterService.countWrongAnswers(answers)
}

answersObservable.subscribe({
    next: _ => {
        /* Only do the following when we received a response from the server, can be either saveAnswers or countWrongAnswers */
    }
})

在您的代码片段中,您可以交换以下代码:

    if(this.questionsForm.valid){
      this.masterService.saveAnswers(answers)
    }

如果你不关心服务器响应,就用这个:

    if(this.questionsForm.valid){
      this.masterService.saveAnswers(answers).subscribe(_=>{})
    }

或者如果您想处理响应:

        if(this.questionsForm.valid){
          this.masterService.saveAnswers(answers).subscribe({
            next: result => {
                displayResult(result)
            },
            error: error => {
                showError(error)
            }
          })
        }
© www.soinside.com 2019 - 2024. All rights reserved.