Http-Get-Function, кажется, вызывается несколько раз за один вызов и всегда возвращает пустой массив - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть класс 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;
    }
}

Мой интерфейс (TS) выполняет следующие действия:

export class ProjectReceiverService {

constructor(
  private http: HttpClient, 
  private logger: LoggerService
) { }

getAllProjects() : ProjectCreator[] {
    let projectArray: ProjectCreator[];

    @PostMapping(value = Constants.CREATE_NEW_PROJECT)
    public ResponseEntity createProject(@RequestBody ProjectDto project) {
        this.logger.info(project.toString());
        return ResponseEntity.ok(HttpStatus.OK);
    }

    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;
  }
}

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();
  }

Вывод в моем браузере:

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.out и немного запутался:

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 "name" и один раз с projectName "test".Тем не менее, регистратор (и, следовательно, API) должен вызываться довольно часто, и атрибут projectList, кажется, повторно инициализируется все время.Может кто-нибудь сказать мне, что там происходит?Почему API вызывается так часто - и что мне делать, чтобы справиться с этим?

Редактировать: я использую Spring-Boot и Angular 7

1 Ответ

0 голосов
/ 11 декабря 2018

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 и вызывается код внутри метода подписки.Этот код обновляет список проектов.

Обычно рекомендуется подписаться на компонент, который использует службу.Мой код выглядит так:

Мой сервис:

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

Мой компонент:

  ngOnInit(): void {

    this.productService.getProducts().subscribe(
      products => this.products = products,
      error => this.errorMessage = <any>error
    );
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...