简体   繁体   English

获取 angular 8 发布 http 请求的问题,Postman 工作正常

[英]Problems with getting angular 8 to post http request, Postman works fine

I'm having some problems getting angular to post my data to the API backend.我在将我的数据发布到 API 后端时遇到了一些问题。 The API works fine with Postman. API 与 Postman 配合良好。

I have a service for the Observable and then I subscribe to it in the component.我有一个 Observable 服务,然后我在组件中订阅它。

What am I trying to do?我想做什么? I'm trying to post to my backend api/database the firstname, lastname and emaladdress from the html form.我正在尝试将 html 表单中的名字、姓氏和 emaladdress 发布到我的后端 api/数据库。 If I use Postman it works perfectly, so I don't see that the problem is with the API part.如果我使用 Postman,它可以完美运行,所以我看不出问题出在 API 部分。 The html has a form in which calls the OnFormSubmit() function. html 有一个调用 OnFormSubmit() 函数的表单。 This in turn calls the createArticle(article) function in the article.component.ts, which uses the articleService.createArticle(article) function in the article.service.ts file.这反过来调用article.component.ts 中的createArticle(article) 函数,该函数使用article.service.ts 文件中的articleService.createArticle(article) 函数。 When I run the CreateArticle(article) the data/values are passed and returned but in the backend api, they are never written.当我运行 CreateArticle(article) 时,数据/值被传递并返回,但在后端 api 中,它们从未被写入。 If I use Postman and add the values for firstname, lastname, and emailaddress it works prefectly.如果我使用 Postman 并添加名字、姓氏和电子邮件地址的值,它就可以完美地工作。

EmailsubControler.cs This is from the backend api, which works fine with postman EmailsubControler.cs这是来自后端api,与邮递员一起工作正常

//Post an entry to email addresses

  [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Post(string firstname, string lastname, string emailaddress)
    {

    var newemailsub = new EmailSubscriptionModel{ Firstname = firstname, Lastname = lastname, Emailaddress = emailaddress};
    await _context.EmailSub.AddAsync(newemailsub);
    await _context.SaveChangesAsync();

    return Ok(newemailsub);

    }

article.component.ts文章.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Observable, Observer } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { ArticleService } from './article.service';
import { Article } from './article';
import { map } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';



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


  constructor(private formBuilder: FormBuilder, private articleService: ArticleService, private http: HttpClient) { }


  get firstname() {
     return this.articleForm.get('firstname');
  }

  get lastname() {
     return this.articleForm.get('lastname');
  }

  get emailaddress() {
     return this.articleForm.get('emailaddress');
  }   
  dataSaved = false;
  articleForm: FormGroup;
  allArticles$: Observable<Article[]>;


  time = new Observable<string>((observer: Observer<string>) => {
    setInterval(() => observer.next(new Date().toString()), 1000);
  });



  ngOnInit() {
    this.articleForm = this.formBuilder.group({

      firstname: ['', [ Validators.required ] ],
      lastname: ['', [ Validators.required ] ],
      emailaddress: ['', [ Validators.required ] ]
    });
    // this.loadAllArticles();


  }
  onFormSubmit() {
    console.log('articleafterdataSaved', this.articleForm.value);
    this.dataSaved = false;
    let article = this.articleForm.value;

    this.articleService.getAllArticles().subscribe(articles => {

      this.createArticle(article);

    });
    this.articleForm.reset();
  }

  createArticle(article) {
    console.log('articledataincreatearticle', article);
    this.articleService.createArticle(article)
    .subscribe(

      Response => console.log('insubscribe-returned:', article),
      this.dataSaved = true,
        this.loadAllArticles()
    );

  }



loadAllArticles() {
     this.allArticles$ = this.articleService.getAllArticles();
  }


} 

article.ts This is the interface article.ts这是界面

export interface Article {
    id?: number;
    firstname: string;
    lastname: string;
    emailaddress: string;
}

article.service.ts article.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { Article } from './article';
import { map } from 'rxjs/operators';
import { catchError, retry } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class ArticleService {
  url = "https://localhost:5001/emailsub";

  constructor(private http: HttpClient) { }


/*   createArticle(article: Article): Observable<Article> {
    console.log('1inservicearticle', article);
    let httpHeaders = new HttpHeaders()
        .set('Content-Type', 'application/json');   
    let options = {
        headers: httpHeaders
    };        
    console.log('inservicearticle', article);
    console.log('inservicearticle', this.url);
   // return this.http.post<Article>(this.url, article, options);
    return this.http.post<Article>(this.url, article, options);
  } */

errorHand1: any;



    httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
    };
  createArticle(article): Observable<Article> {


    console.log('1inservicearticle', article);

    console.log('inservicearticle-article', article);
    console.log('inservicearticle-url', this.url);
    console.log('inservicearticle-JSON', JSON.stringify(article));
   // return this.http.post<Article>(this.url, article, options);
    return this.http.post<Article>(this.url, JSON.stringify(article), this.httpOptions)
    .pipe(
      retry(1),
      catchError(this.errorHand1)
    );




     }













  postArticle(article: Article): Observable<HttpResponse<Article>> {
    let httpHeaders = new HttpHeaders({
         'Content-Type' : 'application/json'
    });    
    console.log('inservice', article.firstname);
    return this.http.post<Article>(this.url, article,
        {
          headers: httpHeaders,
          observe: 'response'

        }

    );
}    


getAllArticles(): Observable<Article[]> {
    return this.http.get<Article[]>(this.url);
}     
} 

article.component.html文章.component.html

<h3>Create Article</h3>
<p *ngIf="dataSaved && articleForm.pristine" ngClass = "success">
    Article created successfully.
</p>
<form [formGroup]="articleForm" (ngSubmit)="onFormSubmit()">
  <table>
     <tr> 
       <td>firstname: </td>
       <td> 
        <input formControlName="firstname">
        <div *ngIf="firstname.dirty && firstname.errors" class = "error"> 
               <div *ngIf="firstname.errors.required"> 
            firstname required.
           </div>   
            </div>
       </td>
     </tr> 
     <tr> 
       <td>lastname: </td>
       <td> 
          <input formControlName="lastname">
          <div *ngIf="lastname.dirty && lastname.errors" class = "error"> 
          <div *ngIf="lastname.errors.required"> 
            lastname required.
          </div>    
          </div>       
       </td>
     </tr>   
     <tr>
       <td>emailaddress: </td>
       <td> 
          <input formControlName="emailaddress">
          <div *ngIf="emailaddress.dirty && emailaddress.errors" class = "error"> 
            <div *ngIf="emailaddress.errors.required"> 
            emailaddress required.
        </div>             
          </div>       
       </td>
     </tr>       
     <tr>     
       <td colspan="2">
          <button [disabled]="articleForm.invalid">Submit</button>
       </td>
     </tr>     
  </table>  
</form>
<h3>Article Details</h3>
<p *ngFor="let article of allArticles$ | async">
    {{article.id}} | {{article.firstname}} | 
  {{article.lastname}} | {{article.emailaddress}}
</p> 
<div><code>observable|async</code>: Time: {{ time | async }}</div>

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

First of all,首先,

you're subscribing to getAllArticles() in your onFormSubmit() , why would you fetch all articles, assign the response to the local articles and not use it?您在getAllArticles()订阅onFormSubmit() ,为什么要获取所有文章,将响应分配给本地articles而不使用它? This code is a mess, 1st remove that subscription to getAllArticles() , because it's out of context of creating a new article.这段代码一团糟,第一次删除对getAllArticles()订阅,因为它脱离了创建新文章的上下文。

  onFormSubmit() {
    console.log('articleafterdataSaved', this.articleForm.value);
    this.dataSaved = false;
    let article = this.articleForm.value;  // not sure if that's the correct way to get the values either, but that's for another time.
    this.createArticle(article);
    this.articleForm.reset();
  }

Then, I assume, you'd like to load all articles after that's done, for whatever reason.然后,我假设,无论出于何种原因,您都希望在完成后加载所有文章。 In your createArticle() function you're subscribing to the response of articleService.createArticle() and updating dataSaved and loading all articles.createArticle()函数中,您订阅了articleService.createArticle()的响应并更新dataSaved并加载所有文章。

  createArticle(article) {
    console.log('articledataincreatearticle', article);
    this.articleService.createArticle(article)
    .subscribe(

      Response => console.log('insubscribe-returned:', article),
      this.dataSaved = true,
        this.loadAllArticles()
    );

  }

however in this.loadAllArticles() you're assigning allArticles$ to be articleService.getAllArticles()但是在this.loadAllArticles()您将allArticles$分配为articleService.getAllArticles()

loadAllArticles() {
   this.allArticles$ = this.articleService.getAllArticles();
}

this of course does nothing unless subscribed.除非订阅,否则这当然什么都不做。

1st pass:第一关:

  createArticle(article) {
    console.log('articledataincreatearticle', article);
    this.articleService.createArticle(article).pipe(
      switchMap(response => {
        console.log('insubscribe-returned:', response);
        this.dataSaved = true;
        return this.articleService.getAllArticles();
      }
    .subscribe(articles => this.articles = articles);
  }

Here we introduced switchMap and pipe() To understand this, you have to look at the map() operator.这里我们介绍了switchMappipe()要理解这一点,你必须看看 map() 操作符。 Observables are a stream of data. Observable 是一个数据流。 rxjs deals with streams of data. rxjs 处理数据流。

You can pipe, just like you would in a linux or macos shell, operators and finally subscribe to the result.您可以使用管道,就像在 linux 或 macos shell 中一样,操作符并最终订阅结果。

Here we switched away from the stream of the articleService.createArticle() Observable, did something inside the function (note the {}) and returned a new Observable stream, articleService.getAllArticles() .这里我们从articleService.createArticle() Observable 的流中切换出来,在函数内部做了一些事情(注意 {})并返回一个新的 Observable 流, articleService.getAllArticles() Then we do whatever with the response of this stream.然后我们对这个流的响应做任何事情。

2nd pass:第二关:

onFormSubmit() {
  this.dataSaved = false;
  const article = this.articleForm.value;
  this.articleService.createArticle(article).pipe(
    tap(data => console.log('response from createArticle:', data)),
    tap(data => this.dataSaved = true),
    switchMap(response => this.articleService.getAllArticles()),
    tap(allArticlesData => console.log('all articles response:', allArticlesData)
  ).subscribe(articles => this.articles = articles)
}

So we did a bunch of stuff.所以我们做了一堆东西。 We tap ped into the stream to log the data.我们tap ped 进入流来记录数据。 We also used the tap operator to change the dataSaved state.我们还使用了tap运算符来更改dataSaved状态。 We then switched away from the stream to return a new stream.然后我们从流切换到返回一个新流。 Tapped into that stream to console.log values.进入该流以获取 console.log 值。 And finally assigned the response of that stream to the local articles member variable.最后将该流的响应分配给本地文章成员变量。

And this is only the tip of the iceberg of issues with your code.这只是您的代码问题的冰山一角。

暂无
暂无

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

相关问题 POST 请求被本地 Angular 应用程序的 CORS 策略阻止,但在 Postman 和 Thunder Client 中工作正常 - POST request blocked by CORS policy from local Angular application but works fine in Postman and Thunder Client 尝试使用Angular访问API时遇到400错误的请求,但是使用PostMan时,它的工作效果很好 - Getting 400 bad request when trying to access an API using Angular, but it works perfectly fine when using PostMan post 请求在 Postman 和 cURL 中有效,但在 Angular 中无效 - The post request works in Postman and in cURL but not in Angular http.delete 在 Postman 上工作正常,但在 Angular 4/Ionic 3 应用程序上无效 - http.delete works fine on Postman but not on Angular 4/Ionic 3 app 离职后的请求被cors阻止,而邮递员工作正常Ionic 4 - ionic post request blocked by cors while postman works fine Ionic 4 角度2 http获取请求不通过节点服务器获取数据,而http发布正常 - angular 2 http get request not fetching data via node server while http post works fine c# asp .net core HTTP POST 请求适用于 Postman,但不适用于我的 Angular 客户端(404 错误) - c# asp .net core HTTP POST Request works with Postman but not with my angular client(404 error) 通过 Postman 发送请求工作正常,但不能通过 Angular 客户端 - Sending Request via Postman works fine but not via angular client Angular 发布请求在 postman 中有效,但在 angular 中无效 - Angular post request works in postman but do not work in angular 离子 HTTP 客户端发布请求跨源错误,但适用于 Postman - Ionic HTTP client post Request cross origin Error , But works on Postman
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM