【问题标题】:TypeError: Converting circular structure to JSON when trying to POST requestTypeError:尝试 POST 请求时将循环结构转换为 JSON
【发布时间】:2016-12-18 18:23:36
【问题描述】:

我收到标题中的错误,这是完整的堆栈跟踪,我不确定它是什么,欢迎任何见解!

browser_adapter.js:84 EXCEPTION: Error in ./ParametersFormComponent class ParametersFormComponent - inline template:3:31BrowserDomAdapter.logError @ browser_adapter.js:84BrowserDomAdapter.logGroup @ browser_adapter.js:94ExceptionHandler.call @ exception_handler.js:65next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.js:84 ORIGINAL EXCEPTION: TypeError: Converting circular structure to JSONBrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:74next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.js:84 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:77next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.js:84 TypeError: Converting circular structure to JSON
    at Object.stringify (native)
    at ParametersFormComponent.onSubmit (http://localhost:4200/main.bundle.js:61451:25)
    at DebugAppView._View_ParametersFormComponent0._handle_ngSubmit_7_0 (ParametersFormComponent.ngfactory.js:1809:28)
    at http://localhost:4200/main.bundle.js:57019:24
    at SafeSubscriber.schedulerFn [as _next] (http://localhost:4200/main.bundle.js:11839:54)
    at SafeSubscriber.__tryOrUnsub (http://localhost:4200/main.bundle.js:48280:16)
    at SafeSubscriber.next (http://localhost:4200/main.bundle.js:48229:22)
    at Subscriber._next (http://localhost:4200/main.bundle.js:48179:26)
    at Subscriber.next (http://localhost:4200/main.bundle.js:48143:18)
    at EventEmitter.Subject._finalNext (http://localhost:4200/main.bundle.js:9733:30)
    at EventEmitter.Subject._next (http://localhost:4200/main.bundle.js:9725:18)
    at EventEmitter.Subject.next (http://localhost:4200/main.bundle.js:9682:14)BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:78next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.js:84 ERROR CONTEXT:BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:81next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
browser_adapter.js:84 DebugContext {_view: _View_ParametersFormComponent0, _nodeIndex: 7, _tplRow: 3, _tplCol: 31}BrowserDomAdapter.logError @ browser_adapter.js:84ExceptionHandler.call @ exception_handler.js:82next @ application_ref.js:348schedulerFn @ async.js:89SafeSubscriber.__tryOrUnsub @ Subscriber.js:225SafeSubscriber.next @ Subscriber.js:174Subscriber._next @ Subscriber.js:124Subscriber.next @ Subscriber.js:88Subject._finalNext @ Subject.js:128Subject._next @ Subject.js:120Subject.next @ Subject.js:77EventEmitter.emit @ async.js:77onError @ ng_zone.js:124onHandleError @ ng_zone_impl.js:74ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233NgZoneImpl.runInnerGuarded @ ng_zone_impl.js:86NgZone.runGuarded @ ng_zone.js:240outsideHandler @ dom_events.js:27ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423
:4200/polyfills.bundle.js:3327 Uncaught EXCEPTION: Error in ./ParametersFormComponent class ParametersFormComponent - inline template:3:31
ORIGINAL EXCEPTION: TypeError: Converting circular structure to JSON
ORIGINAL STACKTRACE:
TypeError: Converting circular structure to JSON
    at Object.stringify (native)
    at ParametersFormComponent.onSubmit (http://localhost:4200/main.bundle.js:61451:25)
    at DebugAppView._View_ParametersFormComponent0._handle_ngSubmit_7_0 (ParametersFormComponent.ngfactory.js:1809:28)
    at http://localhost:4200/main.bundle.js:57019:24
    at SafeSubscriber.schedulerFn [as _next] (http://localhost:4200/main.bundle.js:11839:54)
    at SafeSubscriber.__tryOrUnsub (http://localhost:4200/main.bundle.js:48280:16)
    at SafeSubscriber.next (http://localhost:4200/main.bundle.js:48229:22)
    at Subscriber._next (http://localhost:4200/main.bundle.js:48179:26)
    at Subscriber.next (http://localhost:4200/main.bundle.js:48143:18)
    at EventEmitter.Subject._finalNext (http://localhost:4200/main.bundle.js:9733:30)
    at EventEmitter.Subject._next (http://localhost:4200/main.bundle.js:9725:18)
    at EventEmitter.Subject.next (http://localhost:4200/main.bundle.js:9682:14)
ERROR CONTEXT:
[object Object]
Navigated to http://localhost:4200/?

组件

import {Component} from '@angular/core';
import { FormGroup, FormControl, REACTIVE_FORM_DIRECTIVES, Validators, AbstractControl, Control } from '@angular/forms';
import { Headers, Http, Response } from '@angular/http';

@Component({
    selector: 'parameters-form',
    directives: [REACTIVE_FORM_DIRECTIVES],
    templateUrl: 'form.template.html'
})
export class ParametersFormComponent {
  response: {};

  myForm: FormGroup;

  systemParameters: AbstractControl;
  param: AbstractControl;
  liftOperator: AbstractControl;
  restrictOperator: AbstractControl;
  xInitial: AbstractControl;

  system_arr: number[];
  param_arr: number[];
  restrict_arr: number[];
  lift_arr: number[];
  xinitial_arr: number[];

  constructor(private http: Http) {
    this.myForm = new FormGroup({
      'realisations' : new FormControl('', Validators.required),
      'numConstSteps' : new FormControl('', Validators.required),
      'timeHorizon': new FormControl('', Validators.required),
      'continuationStep' : new FormControl('', Validators.required),
      'continuationStepSign' : new FormControl('', Validators.required),
      'numberOfModelParameters' : new FormControl('', Validators.required),
      'systemParameters' : new FormControl(''),
      'param' : new FormControl(''),
      'netLogoFile' : new FormControl('', Validators.required),
      'numberOfModelVariables' : new FormControl('', Validators.required),
      'restrictOperator' : new FormControl(''),
      'liftOperator' : new FormControl(''),
      'xInitial' : new FormControl('')
    });

    this.system_arr = [];
    this.param_arr = [];
    this.restrict_arr = [];
    this.lift_arr = [];
    this.xinitial_arr = [];
    this.param = this.myForm.controls["param"];
    this.systemParameters = this.myForm.controls['systemParameters'];
    this.restrictOperator = this.myForm.controls['restrictOperator'];
    this.liftOperator = this.myForm.controls['liftOperator'];
    this.xInitial = this.myForm.controls['xInitial'];
  }

  addToArray(event, value: number, target: string): void {
    if (event.which === 13) {

      switch (target) {
        case 'systemParameters':
          this.system_arr.push(value);
          (<Control>this.systemParameters).updateValue('');
          break;
        case 'param':
          this.param_arr.push(value);
          (<Control>this.param).updateValue('');
          break;
        case 'liftOperator':
          this.lift_arr.push(value);
          (<Control>this.liftOperator).updateValue('');
          break;
        case 'restrictOperator':
          this.restrict_arr.push(value);
          (<Control>this.restrictOperator).updateValue('');
          break;
        case 'xInitial':
          this.xinitial_arr.push(value);
          (<Control>this.xInitial).updateValue('');
          break;

      }
    }
  }

  deleteItem(value: any, target: string): void {
    let pos = 0;
    switch (target) {
      case 'systemParameters':
        pos = this.system_arr.indexOf(value);
        this.system_arr.splice(pos, 1);
        break;
      case 'param':
        pos = this.param_arr.indexOf(value);
        this.param_arr.splice(pos, 1);
        break;
      case 'liftOperator':
        pos = this.lift_arr.indexOf(value);
        this.lift_arr.splice(pos, 1);
        break;
      case 'restrictOperator':
        pos = this.restrict_arr.indexOf(value);
        this.restrict_arr.splice(pos, 1);
        break;
      case 'xInitial':
        pos = this.xinitial_arr.indexOf(value);
        this.xinitial_arr.splice(pos, 1);
        break;

    }
  }

  isFullfilled(m: number, n: number) {

    if (
          m == this.restrict_arr.length
          && m == this.xinitial_arr.length
          && m == this.lift_arr.length
          && n == this.param_arr.length
          && n == this.system_arr.length
       ) {
         if (m != 0 && n != 0 ){
           return true;
         }

       }

       return null;
  }
  onSubmit() {

    this.myForm.value.systemParameters = this.system_arr;
    this.myForm.value.liftOperator = this.lift_arr;
    this.myForm.value.restrictOperator = this.restrict_arr;
    this.myForm.value.param = this.param_arr;
    this.myForm.value.xInitial = this.xinitial_arr;

    let Form = JSON.stringify(this.myForm);

    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    this.http.post('http://localhost:3000/webhook', Form, { headers: headers })
    .map((data: Response) => data.json())
    .subscribe(
      data => this.response = data,
      error => console.log(error)
    );

    console.log('your submitted value:', this.myForm.value);
  }

}

在我将它从 Beta 版移植到 RC5 之前工作正常

【问题讨论】:

    标签: angular


    【解决方案1】:

    错误似乎是由于我试图对整个 myForm 对象进行字符串化,而我想要的只是对值进行字符串化

    正确的语法

    let Form = JSON.stringify(this.myForm.value);
    

    【讨论】:

      【解决方案2】:

      这可能是因为对象中的循环依赖。在这种情况下,无法进行字符串化,但始终可以登录到浏览器控制台。所以我们可以为此目的创建一个非常基本的管道。

      app.module.ts:

      import { LogPipe } from './log.pipe';
      
      @NgModule({
        declarations: [
          //...
          LogPipe,
        ],
      })
      export class AppModule {}
      

      log.pipe.ts:

      @Pipe({name: 'log'})
      export class LogPipe implements PipeTransform {
          public transform(value: object): void {
              console.log(value);
              return;
          }
      }
      

      然后我们可以使用管道进行快速记录

      {{'some text' | log}}
      

      【讨论】:

      • 我的项目中没有看到任何“./log/pipe”。我在哪里可以找到这个?我正在使用 Angular 13
      • @RaphaelPinel 你需要创建它这是第二个脚本
      【解决方案3】:

      除了已经提供的答案之外,当您打算发布整个表单值时,您可以执行以下操作。

      表格示例:

      <form #formData="ngForm" (ngSubmit)="submit(formData)">
          <input ngModel="my value" name="email" id="email" ...>
          ...
      </form>
      

      在ts中:

      submit(formData: any) {
          const data = JSON.stringify(formData.value);
          this.myService.postData(data)...
      }
      

      您从formData.value 获取整个表单的值,然后使用JSON.stringify(obj) 进行字符串化

      我希望这会对某人有所帮助。

      【讨论】:

        【解决方案4】:

        使用 form.value 作为以下代码:

              onSubmit(form: NgForm) {
                this.userService.login(form.value).subscribe(
                  (res: any) => {
                    localStorage.setItem('token', res.token);
                    this.router.navigateByUrl('/home');
                  },
                  error => {
                    if (error.status == 400)
                      this.tostarService.error('Invalid Username or password!', 'Authentication Failed');
                    else
                      console.log(error);
        
                  }
                );
              }
        

        【讨论】:

        • 如果可能,请努力提供额外的解释,而不仅仅是代码。此类答案往往更有用,因为它们可以帮助社区成员,尤其是新开发人员更好地理解解决方案的推理,并有助于避免需要解决后续问题。
        【解决方案5】:

        其中一种方法是您也可以使用 Angular 的内置“json”管道。 为此,您需要在组件中添加角度管道, this.myForm 需要传入管道方法。 在模板中,您可以简单地使用{{ myForm.value | json }}

        【讨论】:

          【解决方案6】:

          此代码将无法循环引用:

          JSON.stringify(circularReference);
          

          // TypeError: 循环对象值

          使用下面的代码:

              const getCircularReplacer = () => {
            const seen = new WeakSet();
            return (key, value) => {
              if (typeof value === "object" && value !== null) {
                if (seen.has(value)) {
                  return;
                }
                seen.add(value);
              }
              return value;
            };
          };
          
          JSON.stringify(circularReference, getCircularReplacer());
          

          【讨论】:

            【解决方案7】:

            错误似乎是由于我试图 stringify 整个 myForm 对象而我想要的是 stringify 只是值。

            正确的语法:

            let Form = JSON.stringify(this.myForm.value);
            

            你也可以试试toString()

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-10-05
              • 2016-01-22
              • 2017-06-29
              • 2019-01-05
              • 1970-01-01
              • 1970-01-01
              • 2023-01-31
              • 2020-08-18
              相关资源
              最近更新 更多