Angular Http Get函数似乎在一次调用中被多次调用,并且总是返回一个空数组

Angular Http Get函数似乎在一次调用中被多次调用,并且总是返回一个空数组,angular,rest,spring-boot,Angular,Rest,Spring Boot,我有一个RestController类,在该类中,我将提交的数据保存到数组中该控制器中的API,并希望它在调用方法getAllProjects时返回数组的所有元素 我得到了以下控制器: @RequestMapping("/project") @RestController public class ProjectController { private final Logger logger = LoggerFactory.getLogger(this.getClass());

我有一个RestController类,在该类中,我将提交的数据保存到数组中该控制器中的API,并希望它在调用方法getAllProjects时返回数组的所有元素

我得到了以下控制器:

@RequestMapping("/project")
@RestController
public class ProjectController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private List<ProjectDto> projectList = new ArrayList<ProjectDto>();
    //...
    @GetMapping(value = Constants.GET_ALL_PROJECTS)
    @ResponseBody
    public List<ProjectDto> getAllProjects() {
        this.logger.info("========== Sending following Projects: =========");
        this.projectList.forEach(e -> {this.logger.info(e.getProjectName());});
        return this.projectList;
    }
}
httpOptions:

export const httpOptions = {
    headers: new HttpHeaders({
        'Content-Type':  'application/json'
    })
}
API是在我的组件的onInit方法中调用的:

 ngOnInit() {
    this.logger.info("init dashboard component");
    this.updateAllProjects();
  }

  updateAllProjects() {
    this.logger.info("Getting all Projects");
    this.allProjects = this.projectReceiverService.getAllProjects();
  }
  ngOnInit(): void {

    this.productService.getProducts().subscribe(
      products => this.products = products,
      error => this.errorMessage = <any>error
    );
  }
“我的浏览器”中的输出为:

init dashboard component
dashboard.component.ts:35 Getting all Projects
create-project.service.ts:22 Response: OK
project-receiver.service.ts:22 []length: 0__proto__: Array(0)
core.js:14597 ERROR TypeError: Cannot read property 'forEach' of undefined
    at SafeSubscriber._next (project-receiver.service.ts:23)
所以看起来这个数组是空的。所以我查了一下我的catalina,有点困惑:

2018-12-11 00:02:03.598  INFO 16388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2018-12-11 00:02:03.634  INFO 16388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 34 ms
2018-12-11 00:02:35.308  INFO 16388 --- [nio-8080-exec-5] ProjectController  : ========== Sending following Projects: =========
2018-12-11 00:02:35.373  INFO 16388 --- [nio-8080-exec-3] ProjectController  : ProjectName = name; projectNumber = number; projectArea = area
2018-12-11 00:02:39.042  INFO 16388 --- [nio-8080-exec-7] ProjectController  : ========== Sending following Projects: =========
2018-12-11 00:12:10.185  INFO 16388 --- [nio-8080-exec-2] ProjectController  : ProjectName = name; projectNumber = number; projectArea = area
2018-12-11 00:12:10.196  INFO 16388 --- [nio-8080-exec-3] ProjectController  : ========== Sending following Projects: =========
2018-12-11 00:12:19.106  INFO 16388 --- [nio-8080-exec-7] ProjectController  : ProjectName = test; projectNumber = test; projectArea = test
2018-12-11 00:12:19.121  INFO 16388 --- [nio-8080-exec-5] ProjectController  : ========== Sending following Projects: =========
2018-12-11 00:13:00.895  INFO 16388 --- [nio-8080-exec-4] ProjectController  : ========== Sending following Projects: =========
正如您可能看到的,我只调用了两次API:一次使用projectName,一次使用projectName测试。然而,记录器和api必须被频繁调用,属性projectList似乎一直在重新初始化。有人能告诉我那里发生了什么吗?为什么API调用如此频繁?我应该如何处理


编辑:我使用的是Spring引导和Angular 7,Http是异步的。因此,您将在设置数组之前返回该数组:

    this.http.get('http://localhost:8080/project/getAllProjects', httpOptions).
      subscribe( (res) => {
        this.logger.info(res);
        res['projectList'].forEach( (project) => {
          projectArray.push(project);
        },
        (error) => {
          this.logger.error(error);
        });
      });

    return projectArray;
  }
处理程序如下:

1订阅提交http get请求

2 return语句返回空的projectArray

3从http get请求返回数据,并调用subscribe方法中的代码。此代码更新项目列表

通常,在使用服务的组件中订阅是最佳实践。我的代码如下所示:

我的服务:

  getProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(this.productsUrl)
      .pipe(
        tap(data => console.log(JSON.stringify(data))),
        catchError(this.handleError)
      );
  }
我的组成部分:

 ngOnInit() {
    this.logger.info("init dashboard component");
    this.updateAllProjects();
  }

  updateAllProjects() {
    this.logger.info("Getting all Projects");
    this.allProjects = this.projectReceiverService.getAllProjects();
  }
  ngOnInit(): void {

    this.productService.getProducts().subscribe(
      products => this.products = products,
      error => this.errorMessage = <any>error
    );
  }

谢谢你。但是,当我添加一个新项目,然后稍晚刷新页面时,我应该至少会收到该项目的一个数组,不是吗?我感到困惑的是,无论何时刷新网站,我都没有收到任何答复。。然而,在Spring Boot后端使用@Autowired服务解决了这个问题。对于前端,您的解决方案比我的要优雅得多,所以也感谢您!我仍然有一个问题:什么是tap?我在插入代码时遇到了以下错误,因为类型“Observable”不可分配给类型“ProjectCreator[]”,所以我忽略了catchError。类型“Observable”中缺少属性“length”。“tap”允许您在不修改可观察流的情况下进入可观察流。它通常用于调试,例如在本例中,它记录我们返回的数据。如果没有看到一些新代码,您看到的新错误将很难解决。考虑用这个新的问题来创建一个新的问题,我们来看看。