【问题标题】:Defined variable gets back to undefined inside subscribe已定义的变量返回到未定义的内部订阅
【发布时间】:2020-09-10 08:04:46
【问题描述】:

我是初学者,所以我想我可能做错了什么。 我尝试编写一个 CRUD,允许在创建图像时向团队添加图像。 我将文件名存储在数据库中,然后将图像上传到服务器后端。几天前,一切正常,但从昨天开始,它不会上传文件。这是因为变量this.currentFile(在输入的每次更改时定义)在从 API 接收的数据分配给 this.team(这也是未定义的,而 data 已定义)后返回未定义。

我发现有人说thissubscribe() 中未定义,但我的定义明确。 我真的不知道出了什么问题,我已经做了几个小时了,我没有找到任何可以帮助的东西,所以任何帮助都将不胜感激!

所以这是team-form.component.ts中的submit()方法

submit() {
    this.bindToModel();
    if(this.team.id == undefined) { //this.team and this.currentFile are well defined
      this.teamService.save(this.team).subscribe(
        (data) => {
          this.team = data; //this.team and this.currentFile get back to undefined at this point, even after data was assigned to this.team
          if(this.currentFile != undefined) {
            this.uploadService.upload(this.currentFile, this.team.id).subscribe({
              error: err => showError(this.toasterService, err.error.message),
              complete: () => {
                this.currentFile = null;
              }
            });
          }
        },
        error => showError(this.toasterService, error.message),
        () => { this.closeModalAndMessageSuccess()}
      );
    }else {
      this.teamService.update(this.team).subscribe({
        error: err => showError(this.toasterService, err.error.message),
        complete: () => this.closeModalAndMessageSuccess()
      })
    }
  }

这里是bindToModel() 方法

bindToModel() {
    this.team.contestTypes = this.selectedContestTypes;
    this.selectedContestTypes = [];
    this.team.label = this.teamForm.get('label').value;
    if(this.currentFile != undefined) {
      this.team.logoPath = this.currentFile.name;
    } else {
      this.team.logoPath = null;
    }
  }

selectFile(event)方法在用户选择文件时触发

selectFile(event) {
    let reader = new FileReader();
    if(event.target.files && event.target.files.length > 0) {
      this.currentFile = event.target.files[0];
    }
  }

还有输入的html:

<div class="labelAndUpload">
    <label for="teamLogo"> Logo de l'équipe</label>
    <input type="file"
       id="teamLogo"
       (change)="selectFile($event)">  
</div>

编辑:

所以正如@aditya_adi_98 建议的那样,我打电话上传文件并同时保存团队。 现在我认为我的后端控制器方法语法有问题,因为我遇到了以下错误:

Content type 'multipart/form-data;boundary=---------------------------29202803211777703984242234963' not supported

这是我的新 submit() 方法

  submit() {
    this.bindToModel();
    if(this.team.id == undefined) {
      var stringTeam = JSON.stringify(this.team);
      const frmData = new FormData();
      frmData.append("team", stringTeam);
      frmData.append("file", this.currentFile);

      this.teamService.save(frmData).subscribe({
        error: err => showError(this.toasterService, err.error.message),
        complete: () => this.closeModalAndMessageSuccess()
      });
    } else {
      this.teamService.update(this.team).subscribe({
        error: err => showError(this.toasterService, err.error.message),
        complete: () => this.closeModalAndMessageSuccess()
      })
    }
  }

现在请求

public save(formData: FormData) {
  return this.http.post<Team>(this.teamsUrl, formData);
}

还有后端控制器方法(java)。考虑到我正在传递的文件,它尚未修改,但我只希望该方法目前能够正确接收请求。

@PostMapping(path = TEAMS_URI, consumes = "application/json", produces = "application/json")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<?> createTeam(@Valid @RequestParam("team") Team team, @RequestParam("file") MultipartFile file) throws URISyntaxException {
        String message = bundle.getString(POST_TEAM);
        log.debug(message, team);
        Team teamSave = teamService.createTeam(team);
        return new ResponseEntity<>(teamSave, HttpStatus.CREATED);
}

这里有懂java的可以帮帮我吗?

【问题讨论】:

    标签: java angular spring-boot subscribe


    【解决方案1】:

    您为什么要进行两次 http 调用,而您可以在一次调用中进行此操作..例如使用 this.teamService.save(this.team) 发送文件/图像

      const frmData = new FormData();      
      frmData.append("Upload", this.currentFile);
      frmData.append("team",this.team)      
          
    

    编辑

    你也可以这样做来观察你的文件上传,最好发送一个完整的请求,然后等待响应

    this.http.post(BACKEND_URL+'/testfileupload', frmData,{responseType : 'text',reportProgress:true,observe :'events'})
        .subscribe(      
          (event: HttpEvent<any>)=>{
            switch(event.type){
              case HttpEventType.Sent:
                
                break;
    
              case HttpEventType.ResponseHeader:
                
                break;
    
              case HttpEventType.UploadProgress:
                this.progress = Math.round(event.loaded / event.total * 100);
                this.showupload=true;
                this.changedetector.detectChanges()
                console.log(`uploaded ${this.progress}`);
                break;
    
              case HttpEventType.Response:
                this.showupload=false;
                this.doneupload=true;
                this.progress=0;
                this.currentFile=''
                this.changedetector.detectChanges(); 
                console.log("uploaded successfully")
    
                this.teamaddedsuccessful()
                setTimeout(()=>{
                  this.doneupload=false;
                  this.changedetector.detectChanges();
                  this.modalService.dismissAll();
                  this.toastr.success("File Uploaded Successful","Success")
                  this.filetitle='';},3000)
            }
        
          },res=>{
            if(res.status == 404)
            {
              this.showupload=false;
              this.progress=0;
              this.changedetector.detectChanges(); 
              this.toastr.error("Error in File Upload","Error")
            }
          })
    

    【讨论】:

    • 我认为将文件操作与数据操作分开是一种很好的做法
    • 我无法将 this.team 添加到 formData :'Team' 类型的参数不可分配给'string |斑点'
    • 2 个选项 (1) 像这样对团队进行字符串化: var stringteam = JSON.stringify(this.team) 然后使用 frmData.append("team",stringteam) 或 (2) 像这样单独传递团队参数: frmData.append("team_id",this.team.id) frmData.append("team_contestTypes",this.team.contestTypes)
    • contestTypes 不是字符串,它是一个 ContestType 数组。所以我认为第一个选项是最好的
    • 你是在Api中解析团队[JSON.parse(team)]来使用它..??
    猜你喜欢
    • 2020-08-12
    • 1970-01-01
    • 2018-05-14
    • 2021-04-27
    • 2018-10-19
    • 1970-01-01
    • 2020-08-21
    • 2020-12-18
    • 1970-01-01
    相关资源
    最近更新 更多