Angular Взаимодействие API - Форма Внутренняя ошибка сервера POST & PUT 500 - PullRequest
0 голосов
/ 12 апреля 2020

Я учусь на уроке веб-программирования в колледже, и одним из заданий является создание Angular приложения, которое взаимодействует с пользовательским веб-API, который мы написали с использованием ExpressJS. Приложение представляет собой словарь терминов и использует четыре операции CRUD - создание, чтение, обновление, удаление.

Нам предоставили множество примеров кода для создания нашего приложения, поэтому я активно ссылаюсь на это. Моя дилемма связана с POST и PUT. Когда я ввожу данные в форму и отправляю их, консоль браузера показывает сообщение Внутренняя ошибка сервера 500, а API говорит, что полученные значения не определены. Я написал этот API и использовал его для двух предыдущих заданий, одно из которых было REACT App, и оно работало безупречно. Кажется, я не могу понять, является ли мой компонент службы в Angular виновником, или, может быть, я что-то упустил на стороне API.

Вот фрагменты кода, которые я считаю актуальными (ссылки на GitHub и Херою размещали API ниже). Я ценю помощь, и извините, если это долго. Семестр заканчивается, поэтому я должен передать его ко вторнику!

GitHub:

- https://github.com/mdzura/bti425-a2-web-app

- https://github.com/mdzura/bti425-a2-web-api

- https://bti425-a2-web-api.herokuapp.com/api/

сервер. js

/**********************************************************************************
 * Web service setup - Packages for handling data and requests.                   *
 **********************************************************************************/
const express = require("express");
const cors = require("cors");
const path = require("path");                             // 'path' is for dirctories.
const bodyParser = require('body-parser');
const app = express();                                    // Links Express for Node Server.
const HTTP_PORT = process.env.PORT || 8080;               // Sets the http port to 8080.


const manager = require("./manager.js");                  // MongoDB Data model and API request handling.


app.use(bodyParser.json());                               // Add support for incoming JSON entities.
app.use(cors());                                          // Add support for CORS.


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

// ********************** Add new **************************//
app.post("/api/term/english/add", function (req, res) {

  res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
  res.setHeader("Access-Control-Allow-Headers", "Authorization, Cache-Control, Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

  console.log("POSTING data");

  manager.termEnglishAdd(req.body)                                  // Call the manager method
         .then(function(data) {
           console.log(data);
           res.status(201).json(data);
         })
         .catch(function(error) {
            res.status(500).json({ "message": error });
         })
});
/*************************************************************/

// ***************** Edit existing **************************//
app.put("/api/term/english/edit/:id", function (req, res) {

  console.log("By ID: " + req.body.id);

  if (req.body.id != req.body.id) {
    res.status(404).json({ "message": "Resource not found" });
  }
  else {

    manager.termEnglishEdit(req.params)                               // Call the manager method
    .then(function(data) {
      res.json(data);
    })
    .catch(function(error) {
       res.status(500).json({ "message": error });
    })
  }
});
/*************************************************************/

управление. js

const mongoose = require("mongoose");                                                                  
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);


const termEnglishSchema = require("./msc-termEnglish.js");                                             
const definitionSchema = require("./msc-definition");   


/******************************************************************************
 * Initializes Connection to Database                                         *
 ******************************************************************************/
let Dictionary;                                                                                        // Collection Properties
module.exports.initialize = function() {
    return new Promise(function(resolve, reject) {
        let db = mongoose.createConnection("mongodb://localhost:27017/db-a2", { connectTimeoutMS: 5000, useUnifiedTopology: true });

        db.on('error', function (err) {
            reject(console.log(err.message));                                                         
        });
        db.once('open', function () {
            Dictionary = db.model("englishterms", termEnglishSchema, "englishterms");                

            console.log(Dictionary);
            resolve(console.log("Database Connected"));
        });
    });
};
/*******************************************************************************/

/******************************************************************************
 * Add English Term to the Database                                           *
 ******************************************************************************/
module.exports.termEnglishAdd = function (newItem) {
    console.log("Adding English Term to Collection...");
    console.log(newItem);
    return new Promise(function (resolve, reject) {

        //var newTerm = new Dictionary(newItem);
        // Find one specific document
        Dictionary.create(newItem, function (error, item) {
            if (error) {
              // Cannot add item
              console.log(error.message);
              return reject(error.message);
            }
            //Added object will be returned
            console.log(item);
            return resolve(item);
        });
    });
};
/*******************************************************************************/

/******************************************************************************
 * Edit existing English Term from the Database                               *
 ******************************************************************************/
module.exports.termEnglishEdit = function (changes) {
    console.log("Editing English Term in Collection...");

    //changes.id has values, but changes.wordEnglish and all the others are coming empty.
    console.log("Changes: " + changes.id + ", " + changes.wordEnglish);

    return new Promise(function (resolve, reject) {
        // Find one specific document
        Dictionary.findByIdAndUpdate(changes.id, 
            {
                wordEnglish: changes.wordEnglish,
                wordNonEnglish: changes.wordNonEnglish,
                wordExpanded: changes.wordExpanded,
                languageCode: changes.languageCode,
                image: changes.images,
                imageType: changes.imageType,
                audio: changes.audio,
                audioType: changes.audioType,
                linkAuthoritative: changes.linkAuthoritative,
                linkWikipedia: changes.linkWikipedia,
                linkYouTube: changes.linkYouTube,
                authorName: changes.authorName,
                dateCreated: changes.dateCreated,
                dateRevised: changes.dateRevised,
                fieldOfStudy: changes.fieldOfStudy,
                helpYes: changes.helpYes,
                helpNo: changes.helpNo,
                definitions: [{
                    authorName: changes.definitions.authorName,
                    dateCreated: changes.definitions.dateCreated,
                    definition: changes.definitions.definition,
                    quality: changes.definitions.quality,
                    like: changes.definitions.like
                }]
            }, function (error, item) {
            if (error) {
              // Cannot edit item
              return reject(console.log(error.message));
            }
            // Check for an item
            if (item) {
              // Edited object will be returned
              return resolve(item);
            } else {
              return reject(console.log("Not Found!"));
            }
        });
    });
};

edit-term.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from "@angular/router";

import { DataManagerService } from './data-manager.service';
import { Router } from "@angular/router";
import { NgForm } from '@angular/forms';

import { TermEnglish, Definition } from "./data-class";
import { from } from 'rxjs';

@Component({
  selector: 'app-edit-term',
  templateUrl: './edit-term.component.html',
  styleUrls: ['./edit-term.component.css']
})
export class EditTermComponent implements OnInit {

// Data-holding properties
term: TermEnglish;
changeTerm: TermEnglish;
currentDate = new Date;

constructor(private manager: DataManagerService, private router: Router, private route: ActivatedRoute) {

  // Define the user objects
  this.changeTerm = new TermEnglish();
}

ngOnInit() {

  // If required, go and get data that would be needed to render the form
  this.changeTerm.dateRevised = this.currentDate.toLocaleDateString();

  // Get the route parameter
  let id = this.route.snapshot.params['id'];

  // this.manager.englishGetByID(id).subscribe(response => this.changeTerm = response);
  this.manager.englishGetByID(id).subscribe(response => {
    this.term = response;
    this.changeTerm._id = this.term._id;
    this.changeTerm.wordEnglish = this.term.wordNonEnglish;
    this.changeTerm.wordNonEnglish = this.term.wordNonEnglish;
    this.changeTerm.wordExpanded = this.term.wordExpanded;
    this.changeTerm.languageCode = this.term.languageCode;
    this.changeTerm.image = this.term.image;
    this.changeTerm.imageType = this.term.imageType;
    this.changeTerm.audio = this.term.audio;
    this.changeTerm.audioType = this.term.audioType;
    this.changeTerm.linkAuthoritative = this.term.linkAuthoritative;
    this.changeTerm.linkWikipedia = this.term.linkWikipedia;
    this.changeTerm.linkYouTube = this.term.linkYouTube;
    this.changeTerm.authorName = this.term.authorName;
    this.changeTerm.dateCreated = this.term.dateCreated;
    this.changeTerm.dateRevised = this.term.dateRevised;
    this.changeTerm.fieldOfStudy = this.term.fieldOfStudy;
    this.changeTerm.helpYes = this.term.helpYes;
    this.changeTerm.helpNo = this.term.helpNo;
    this.changeTerm.definitions = this.term.definitions;
  });
};

// Form submit button handler
editTerm(): void {

  // Send request
  // this.manager.englishTermEdit(this.term._id, this.changeTerm).subscribe(t => this.changeTerm = t);
  this.manager.englishTermEdit(this.changeTerm).subscribe(t => this.changeTerm = t);

  this.router.navigate(['/terms']);
}

}


data.service.ts:

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

// Import data model classes, for example...
import { TermEnglish } from "./data-class";


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

 // Inject the HttpClient
 constructor(private http: HttpClient) { }

 // Base URL for the web API
 private url: string = 'http://localhost:8080/api';

 // Options object for POST and PUT requests
 private httpOptions = {
   headers: new HttpHeaders({
     'Content-Type': 'application/json'
   })
 };

 // Error handler, from the Angular docs
 private handleError<T>(operation = 'operation', result?: T) {
   return (error: any): Observable<T> => {

     console.error(error); // log to console instead

     return of(result as T);
   };
 }

 // ############################################################
 // Data service operations.

 // Add new
 englishTermAdd(newItem: TermEnglish): Observable<TermEnglish> {
   return this.http.post<TermEnglish>(`${this.url}/term/english/add`, newItem, this.httpOptions)
     .pipe(
       tap((newItem: TermEnglish) => console.log(`Added Term ${newItem.wordEnglish}`)),
       catchError(this.handleError<TermEnglish>('Term add'))
     );
 }

 // Edit existing
 englishTermEdit(newItem: TermEnglish): Observable<TermEnglish> {
   console.log("EditByID=" + `${this.url}/term/english/edit/${newItem._id}`);
   console.log(`Added \n Word: ${newItem.wordEnglish}
             \n NonEnglish Word: ${newItem.wordNonEnglish}
             \n Expanded Word: ${newItem.wordExpanded}
             \n Image: ${newItem.image}
             \n Audio: ${newItem.audio}
             \n URL: ${newItem.linkAuthoritative}
             \n Wiki: ${newItem.linkWikipedia}
             \n Youtube: ${newItem.linkYouTube}
             \n Author: ${newItem.authorName}
             \n Definition: ${newItem.definitions[0].definition}`);
   return this.http.put<TermEnglish>(`${this.url}/term/english/edit/${newItem._id}`, newItem, this.httpOptions)
     .pipe(
       tap((newItem: TermEnglish) => console.log(`Edited item ${newItem.wordEnglish}`)),
       catchError(this.handleError<TermEnglish>('Term edit'))
     );
 }
}

1 Ответ

0 голосов
/ 12 апреля 2020

Возможно, вы можете использовать PostMan , чтобы протестировать ваш API и убедиться, что он работает правильно после этого, если ошибка все еще существует, то, возможно, проблема в вашем angular коде, и на этом этапе вы могли бы поделиться более детали, чтобы я мог помочь вам

...